int foo;
int? bar;
if (bar != null)
{
foo = bar; // does not compile
foo = (int)bar; // compiles
foo = bar.Value; // compiles
}
我很早就知道第一个陈述不正确,但它总是让我烦恼。我已经验证bar
不为空,那么为什么编译器会抱怨?
答案 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;
}