2013-01-24 13 views
6

可能性の重複をコンパイル:
C# okay with comparing value types to null比較 'INT' は

私は、私はちょうど今、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.' 

あなたはintnullを割り当てることができない場合は、なぜコンパイラは(それが唯一の警告を与える)あなたがそれらを比較することができるのですか?興味深いことに

は、コンパイラは、次のことはできません。

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;エラーNullable型には値が必要ですが、 'intをコンパイルしますか? z =(int?)(int?)null; 'それをテストしてください。幸運と幸せコーディング – MethodMan

答えて

7

比較が行われると、コンパイラは、比較の両方のオペランドに互換性のある型ができるようにしようとします。

値はintであり、値はnull(特定のタイプはありません)です。 2つの値の唯一の互換性のある型はint?なので、int?に強制され、int? == int?と比較されます。 int?のような一部のintの値は絶対にnullではなく、nullは間違いなくnullです。コンパイラはそれを認識し、NULL以外の値が確定値nullの値に等しくないため、警告が表示されます。

+0

コンパイラは、常にfalseであるため、これを最適化します。それは 'x'変数をまったくロードしません。 –

+0

'Nullable 'をサポートしていない.NETフレームワークのバージョンでコンパイルしますか? – Guillaume

+0

@ギヨーム:私は正直であるかどうかはわかりませんが、私はそう思います。私は彼らがその場合のオブジェクトとして比較されると思います(同じ警告があります)。 –

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