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

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

私は長い間、最初のステートメントが間違っていることは知っていましたが、常に私を悩ませました。私はbarがnullでないことを確認しました。なぜコンパイラが不平を言っていますか?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

これは質問の文字に答えますが、精神ではないと思います。問題の精神は、「ナル化可能な変換演算子はなぜ暗黙的ではなく明示的に宣言されるのですか? '' '編集:' ''実際には、それはなぜ答えます。私の悪い。 – Medinoc

21

比較は、nullではありませんが、コンパイラは引き続きタイプを使用して割り当てができるかどうかを確認します。

以下は、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

関連する問題