int foo;
int? bar;
if (bar != null)
{
foo = bar; // does not compile
foo = (int)bar; // compiles
foo = bar.Value; // compiles
}
我認識了很久的第一條語句是不正確的,但它一直竊聽我。我已驗證bar
不爲空,那爲什麼編譯器會抱怨?爲什麼在檢查null之後需要顯式轉換?
int foo;
int? bar;
if (bar != null)
{
foo = bar; // does not compile
foo = (int)bar; // compiles
foo = bar.Value; // compiles
}
我認識了很久的第一條語句是不正確的,但它一直竊聽我。我已驗證bar
不爲空,那爲什麼編譯器會抱怨?爲什麼在檢查null之後需要顯式轉換?
類型的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
聲明主體......但編譯器並沒有試圖弄清楚這一點。
雖然這可能看起來愚蠢的,它使語言規則顯著簡單。
的比較只是說 - 它不是null
,編譯器還使用類型,看看是否分配可。
以下將編譯即使沒有空檢查。
foo = (int)bar;
編譯器只檢查你的程序在語法上是否正確。它不關心你的空檢查。
編譯器看到的,你可能會失去信息給予一個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;
}
是不是'(int)foo'和'foo.Value'也不是線程安全的? – Stijn
我認爲這回答問題的信件,但不是精神。問題的精神在於:「爲什麼'Nullable'的轉換運算符聲明爲'explicit'而不是'implicit'?」 '''編輯:'''其實,它確實回答了原因。我的錯。 – Medinoc