为什么null需要显式类型转换?

时间:2010-04-09 15:54:04

标签: c# .net casting null

以下代码无法编译:

//int a = ...
int? b = (int?) (a != 0 ? a : null);

为了编译,需要将其更改为

int? b = (a != 0 ? a : (int?) null);

由于b = nullb = a都是合法的,这对我来说没有意义。

为什么我们必须将null强制转换为int??为什么我们不能简单地为整个表达式提供一个显式的类型转换(我知道在其他情况下是可能的)? / p>

6 个答案:

答案 0 :(得分:18)

从C#语言规范的第7.13章开始:

  

?:运算符的第二个和第三个操作数控制条件表达式的类型。设X和Y是第二个和第三个操作数的类型。然后,

     
      
  • 如果X和Y是相同的类型,则这是条件表达式的类型。
  •   
  • 否则,如果从X到Y存在隐式转换(第6.1节),而不是从Y到X,则Y是条件表达式的类型。
  •   
  • 否则,如果从Y到X存在隐式转换(第6.1节),而不是从X到Y,则X是条件表达式的类型。
  •   
  • 否则,无法确定表达式类型,并发生编译时错误。
  •   

在您的情况下,没有从int到null的隐式转换,反之亦然。你的演员解决了这个问题,int可以转换为int?

答案 1 :(得分:5)

?:运算符的两个备选方案必须属于同一类型。 否则,编译器无法推断出整个条件表达式的类型。

null不是int,因此您需要向编译器提示结果类型为int?


编辑:正如其他人指出的那样,这两种类型不需要相同,但其中一种应该可以转换为另一种(另一种将是结果类型)。有关详细信息,请参阅specs

答案 2 :(得分:5)

如果您使用default(int?)代替null,则可以避免投射。

int a = 42;
int? b = (a != 0 ? a : default(int?));

答案 3 :(得分:1)

这是因为当你使用那种表示法时,两个成员必须属于同一类型,所以你必须明确说“这个成员是一个int?”。

很清楚吗?

答案 4 :(得分:1)

当您使用具有不同类型操作数的条件运算符时,编译器将检查其中一种类型是否可以隐式转换为另一种类型。

如果两种类型都不能隐式转换为另一种类型,它将产生错误,即使存在可以隐式转换为的第三种类型。编译器不会立即在两端插入隐式转换。

在您的情况下,intnull都要求隐式转换成为int?,因此无效。
您需要更改代码,以便一方是int?,而另一方可以隐式转换为int?。简单的方法是将null替换为new int?(),如下所示:

int? b = (a != 0 ? a : new int?());

这只需要一次隐式转换(intint?)。

答案 5 :(得分:0)

对于条件运算符,这几乎是one我的问题的重复。它不是空的,它确实是:

接受的答案非常好,来自Eric Lippert,他是C#编译团队的成员。