为什么在检查null后需要显式转换?
本文关键字:显式转换 检查 null 为什么 | 更新日期: 2023-09-27 18:14:45
int foo;
int? bar;
if (bar != null)
{
foo = bar; // does not compile
foo = (int)bar; // compiles
foo = bar.Value; // compiles
}
我早就知道第一句话是不正确的,但它一直困扰着我。我已经验证了bar
不是null,那么为什么编译器会抱怨呢?
比较只是说-它不是null
,编译器仍然使用类型来查看是否可以进行赋值。
即使没有null检查也可以编译。
foo = (int)bar;
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
语句体…但是编译器并没有试图找出这个
虽然这看起来很愚蠢,但它使语言规则大大简化。
编译器只检查你的程序是否语法正确。它不关心你的空支票。
编译器发现你可能会丢失赋值int类型的信息。到int,因此它会报错
想象一下:如果您有一个类型为Nullable<int>
的成员变量,该变量由多个线程访问,该怎么办?让我们看看在这些情况下的代码。
if(foo != null)
{
// expensive operation that takes time.
// what if another thread as nulled foo in the meantime?
int bar = foo;
}