int foo;
int? bar;
if (bar != null)
{
foo = bar; // does not compile
foo = (int)bar; // compiles
foo = bar.Value; // compiles
}
我早就知道第一句话是不正确的,但它一直困扰着我。我已经验证它bar
不为空,那么为什么编译器会抱怨呢?
int foo;
int? bar;
if (bar != null)
{
foo = bar; // does not compile
foo = (int)bar; // compiles
foo = bar.Value; // compiles
}
我早就知道第一句话是不正确的,但它一直困扰着我。我已经验证它bar
不为空,那么为什么编译器会抱怨呢?
比较只是说 - 不是null
,编译器仍然使用类型来查看是否可以进行赋值。
即使没有空检查,以下也会编译。
foo = (int)bar;
的类型bar
仍然是int?
,并且没有从int?
to的隐式转换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
体……但编译器不会试图弄清楚这一点。
尽管这看起来很愚蠢,但它使语言规则变得更加简单。
编译器只检查你的程序在语法上是否正确。它不关心你的空检查。
编译器发现您可能会丢失分配 int 的信息?到 int ,因此它抱怨。
想象一下:如果你有一个类型为 as 的成员变量Nullable<int>
,它被多个线程访问会怎样。让我们看看你在这种情况下的代码。
if(foo != null)
{
// expensive operation that takes time.
// what if another thread as nulled foo in the meantime?
int bar = foo;
}