我宣布变量
IList<int> list;
然后我写了声明,
if(true)
{
list = new List<int>();
}
else
{
list = new int[0];
}
我有琐碎无意义的代码,可以在没有警告的情况下进行编译。如果我写声明,
list = true ? new List<int>() : new int[0];
我收到编译器警告,
'System.Collections.Generic.List&lt; int&gt;'之间没有隐式转换和'int []'
为什么三元运算符有此限制? List<int>
和int[]
都实现了IList<int>
。
来自C#5.0规范的 7.14条件运算符
?:运算符的第二个和第三个操作数x和y控制条件表达式的类型。
如果x的类型为X且y的类型为Y,则
如果从X到Y存在隐式转换(第6.1节),而不是从Y到X,则Y是条件表达式的类型。
如果从Y到X存在隐式转换(第6.1节),而不是从X到Y,则X是条件表达式的类型。
否则,无法确定表达式类型,并发生编译时错误。
如果x和y中只有一个具有类型,并且x和y都可以隐式转换为该类型,那么这就是条件表达式的类型。
否则,无法确定表达式类型,并发生编译时错误。
答案 0 :(得分:6)
list
的分配不是问题。这是表达式true ? new List<int>() : new int[0]
的问题。在任何情况下,这种表达都是不合法的。
如果您参考documentation,您会找到此信息。
first_expression和second_expression的类型必须相同,或者从一种类型到另一种类型必须存在隐式转换。
在这种情况下,情况并非如此。
答案 1 :(得分:2)
List<int>
和int[]
都实现了很多内容(IEnumerable<int>
,IReadOnlyCollection<int>
等。编译器很难在不给出提示的情况下知道你的意思:
list = true ? (IList<int>) new List<int>() : new int[0];
请记住,表达式是从里到外进行评估的。因此,在编译器查看您尝试将其分配给的内容之前,将对您的三元运算符进行求值。因此,必须存在某种隐式转换,从一侧的类型到另一侧的类型。
在您的if / else示例中,您有效地将List<int>
转换为IList<int>
作为自己的操作,而不是先尝试将其与int[]
合并。