为什么检查null后需要显式转换?

时间:2013-05-22 12:58:14

标签: c#

int foo;
int? bar;

if (bar != null)
{
    foo = bar; // does not compile
    foo = (int)bar; // compiles
    foo = bar.Value; // compiles
}

我很早就知道第一个陈述不正确,但它总是让我烦恼。我已经验证bar不为空,那么为什么编译器会抱怨?

4 个答案:

答案 0 :(得分:21)

比较只是说 - 它不是null,编译器仍然使用类型来查看是否可以进行分配。

即使没有空检查,也会编译。

foo = (int)bar; 

答案 1 :(得分:17)

bar的类型仍为int?,并且没有从int?int的隐式转换。

条件不会改变后面代码的有效性。其他演员也是如此:

object x = ...;
if (x is string)
{
    string y = x; // This is still invalid
    string z = (string) x; // This is fine
} 

编译器很少使用一段代码的结果来影响另一段代码的有效性。另一个例子:

bool condition = ...;
string x;
if (condition)
{
    x = "yes";
}
if (!condition)
{
    x = "no";
}
Console.WriteLine(x); // Invalid

最后一行无效,因为x仍未明确分配。 我们知道无论x的价值是什么,我们都会输入那些if语句体的一个 ...但是编译器没有试着解决这个问题。

虽然这看起来很愚蠢,但它使语言规则变得更加简单。

答案 2 :(得分:3)

编译器仅检查您的程序在语法上是否正确。它不关心你的空检查。

编译器发现你可能会丢失分配int的信息?到int,因此抱怨。

答案 3 :(得分:1)

想象一下:如果你有一个类型为Nullable<int>的成员变量,它被几个线程访问了怎么办?在这种情况下,让我们看看你的代码。

if(foo != null)
{
    // expensive operation that takes time.
    // what if another thread as nulled foo in the meantime?
    int bar = foo;
}