2013-01-24 26 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