这就是我想要做的事情:
XmlWriter writer = XmlWriter.Create(
(string.IsNullOrEmpty(outfile) ? Console.Out : outfile)
);
但是,这不会编译,因为“System.IO.TextWriter”和“string”之间没有隐式转换,因此无法确定错误“条件表达式的类型”。上面的代码简化了以下内容:
XmlWriter writer;
if (string.IsNullOrEmpty(outfile))
{
writer = XmlWriter.Create(Console.Out); // Constructor takes TextWriter
}
else
{
writer = XmlWriter.Create(outfile); // Constructor takes string
}
对Create
的这两次调用完全有效,并且编译。有没有办法让这个更紧凑,就像我试图用我的内联测试一样?
对我来说,我想要的东西不起作用是没有意义的。仔细考虑这一点,似乎编译器会评估string.IsNullOrEmpty(outfile)
以确定要采取的案例:
Console.Out
一致,然后看到它需要以多态方式选择带有TextWriter的XmlWriter.Create
版本。outfile
,然后看到它需要以多态方式选择带有字符串的XmlWriter.Create
版本。ML编程是否扭曲了我的大脑?
答案 0 :(得分:18)
你不能这样做的原因是因为编译器必须选择在编译时使用哪个Create重载 - 你的方法需要在运行时完成。你可以做的最短的可能是:
XmlWriter writer = String.IsNullOrEmpty(outfile)
? XmlWriter.Create(Console.Out)
: XmlWriter.Create(outfile);
答案 1 :(得分:7)
每个人似乎都在暗示以下内容:
XmlWriter writer = String.IsNullOrEmpty(outfile)
? XmlWriter.Create(Console.Out)
: XmlWriter.Create(outfile);
然而,这也是可行的:
XmlWriter writer = XmlWriter.Create(string.IsNullOrEmpty(outfile)
? Console.Out : new StreamWriter(outfile));
后者更接近您原来的尝试,IMO更紧凑。
答案 2 :(得分:3)
C#编译器选择在编译期间静态执行的方法。编译时生成的IL是对特定方法的引用。当多态性部分选择要执行的特定函数的实现时,它会在运行时进入。
您的?:语句在运行时进行评估,因此编译器无法确定要执行的方法。
更改为此,它将起作用。
XmlWriter writer = string.IsNullOrEmpty(outfile) ?
XmlWriter.Create(Console.Out) :
XmlWriter.Create(outfile);
答案 3 :(得分:2)
问题是你无法在编译时确定什么
(string.IsNullOrEmpty(outfile) ? Console.Out : outfile)
应该回来。它会成为一个字符串还是一个TextWriter?那只能在运行时确定,因此编译错误是因为?必须在编译时解析运算符。
你能摆脱它的最好方法可能是:
XmlWriter writer = string.IsNullOrEmpty(outfile)
? XmlWriter.Create(Console.Out)
: XmlWriter.Create(outfile);
答案 4 :(得分:2)
这里发生了一些事情。
首先,由于三元运算符(tm)而发生“异常”,而不是因为你在哪里使用它。问题是因为你有一个单独的表达式试图返回两个不能解析为单个公共基类型(不是对象)的不同类型。
此外,构造函数重载可能需要两种完全不同的类型,这些类型无论如何都不相关。 C#编译器非常非常智能,但它不是 智能。
答案 5 :(得分:1)
不,你必须进行两次单独的调用,因为它们是两个独立的构造函数。
在编译时确定要调用的重载,因此您无法在运行时选择数据类型来调用不同的重载。
此外,条件运算符只能返回单个数据类型,根据选择,您不能返回不同的数据类型。
答案 6 :(得分:1)
C#是静态类型的所有多态性魔法正在编译时发生。并且在编译时不知道条件表达式的类型。