2013-01-24 25 views
6

可能重复:
C# okay with comparing value types to null'诠释' 相较于 '空' 编译

我来到了一个跨东西,我在C#找怪(4.0)编译刚才。

int x = 0; 
if (x == null) // Only gives a warning - 'expression is always false' 
    x = 1; 

int y = (int)null; // Compile error 
int z = (int)(int?)null; // Compiles, but runtime error 'Nullable object must have a value.' 

如果您不能分配nullint,为什么编译器还允许你对他们比较(只给出了一个警告)?

有趣的是,编译器不允许以下:

struct myStruct 
{ 
}; 

myStruct s = new myStruct(); 
if (s == null) // does NOT compile 
    ; 

为什么struct例子不能编译,但int例子呢?

+0

可能做的很警告你所提到的。编译器可能会将其编译为“if(false)”。哪一个是正确的,'x'永远不能是'null'。 –

+0

学习如何使用'?'这不会编译'int? y =(int)null;'但是在运行时这会编译'int? y =(int?)null;'你明白'?'的作用了吗? – MethodMan

+0

也不会编译'int? z =(int)(int?)null;错误可空类型必须有一个值'但是这会编译'int? z =(int?)(int?)null;'测试出来..祝您好运并且编码愉快 – MethodMan

回答

7

当进行比较时,编译器会尝试将其设置为使得比较的两个操作数尽可能具有兼容类型。

它有一个int值和一个常数null值(没有特定类型)。两个值之间唯一的兼容类型是int?,因此它们被强制为int?,并与int? == int?进行比较。一些int值作为int?肯定是非空的,而null肯定是空的。编译器意识到,并且由于非空值不等于确定的值,因此会给出警告。

+0

编译器也将其优化,因为它总是假的。它甚至不会加载'x'变量。 –

+0

它是否在不支持'Nullable ''的.NET框架版本中编译? – Guillaume

+0

@Guillaume:我不确定是否诚实,但我想是的。我想他们会在这种情况下作为'object'进行比较(并且会有相同的警告)。 –

1

实际编译允许比较'int?'到'int'而不是'int'为null有意义

例如,

 int? nullableData = 5; 
     int data = 10; 
     data = (int)nullableData;// this make sense 
     nullableData = data;// this make sense 

     // you can assign null to int 
     nullableData = null; 
     // same as above statment. 
     nullableData = (int?)null; 

     data = (int)(int?)null; 
     // actually you are converting from 'int?' to 'int' 
     // which can be detected only at runtime if allowed or not 

,这就是你正在尝试,因为在int z = (int)(int?)null;

+0

这是合理的。 – rhughes