Eri*_*fer 5 .net c# compiler-construction
我刚刚遇到这个(编写代码来演示"问题"):
public ICollection<string> CreateCollection(int x)
{
ICollection<string> collection = x == 0
? new List<string>()
: new LinkedList<string>();
return collection;
}
Run Code Online (Sandbox Code Playgroud)
编译器抱怨:
Fehler CS0173:Der Typ des bedingten Ausdrucks kann nicht bestimmt werden,weil keine implizite Konvertierung zwischen"System.Collections.Generic.List"und"System.Collections.Generic.LinkedList"erfolgt.
其翻译大致为:
无法确定条件运算符的类型,因为List和LinkedList之间没有隐式转换.
我可以看到为什么编译器抱怨,但是,嘿,来吧.它试图发挥愚蠢.我可以看到两个表达式不是同一类型,而是有一个共同的祖先,作为奖励,左侧的类型也是共同的祖先.我相信编译器也可以看到它.如果左侧被声明为,我可以理解错误var
.
我在这里错过了什么?
编辑:
我接受詹姆斯·冈特的解释.也许只是为了说清楚.我可以很好地阅读编译器规范.我想了解原因.为什么有人决定以这种方式编写规范.这种设计背后必然有一个原因.根据詹姆斯的说法,设计原则是"毫无意外".此外,CodeInChaos还解释了如果编译器试图从常见的祖先中推断出类型,您可能遇到的惊喜.
Jam*_*unt 10
表达式(a?b:c)必须解析为一种类型.类型将是b或c的类型.如果它们不同(并且没有从一个到另一个的隐式转换),则编译器在编译时不知道这是哪种类型.
您可能会说它应该推断出存在共同的根类型,但总有一个共同的根类型(例如Object).
通常,C#编译器不会尝试猜测你的意思.如果要使用公共根类型,则将b和c强制转换为该类型.
这样的逻辑运行,整个C#的设计,它是偶尔有点讨厌,但远远更多的时候它阻止你犯错.