2013-05-22 61 views
11
int foo; 
int? bar; 

if (bar != null) 
{ 
    foo = bar; // does not compile 
    foo = (int)bar; // compiles 
    foo = bar.Value; // compiles 
} 

我認識了很久的第一條語句是不正確的,但它一直竊聽我。我已驗證bar不爲空,那爲什麼編譯器會抱怨?爲什麼在檢查null之後需要顯式轉換?

回答

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聲明主體......但編譯器並沒有試圖弄清楚這一點。

雖然這可能看起來愚蠢的,它使語言規則顯著簡單。

+0

我認爲這回答問題的信件,但不是精神。問題的精神在於:「爲什麼'Nullable'的轉換運算符聲明爲'explicit'而不是'implicit'?」 '''編輯:'''其實,它確實回答了原因。我的錯。 – Medinoc

21

的比較只是說 - 它不是null,編譯器還使用類型,看看是否分配可。

以下將編譯即使沒有空檢查。

foo = (int)bar; 
3

編譯器只檢查你的程序在語法上是否正確。它不關心你的空檢查。

編譯器看到的,你可能會失去信息給予一個int? int,因此它抱怨。

1

想象一下:如果你遇到了什麼類型爲Nullable<int>一個成員變量,這是由多個線程訪問。在這種情況下,我們來看看你的代碼。

if(foo != null) 
{ 
    // expensive operation that takes time. 
    // what if another thread as nulled foo in the meantime? 
    int bar = foo; 
} 
+0

是不是'(int)foo'和'foo.Value'也不是線程安全的? – Stijn

相關問題