2008-09-15 6 views
5

コンパイラ例外投げるだろう、私は例としてintを使用していますが、これはネット1で、.NET.Net 2+:なぜ(1 == null)でもコンパイラの例外がスローされないのですか?

の任意の値タイプに以下を適用する:.NET 2で(今

int i = SomeFunctionThatReturnsInt(); 

if(i == null) //compiler exception here 

をまたは3.5)例外がなくなった。これはなぜ

は、私が知っている:

int? j = null; //nullable int 

if(i == j) //this shouldn't throw an exception 

問題はint?がNULL可能であるとintので、今int?への暗黙的なキャストを持っていることです。上記の構文はコンパイラの魔法です。本当に私たちがやっている:我々はi == nullを行う際

Nullable<int> j = null; //nullable int 

//compiler is smart enough to do this 
if((Nullable<int>) i == j) 

//and not this 
if(i == (int) j) 

をだから今、我々が得る:C#はとにかくこれを計算するために、なぜそれが十分にスマートすることはできませんコンパイラのロジックをやっている

if((Nullable<int>) i == null) 

考えることnullのような絶対値を扱うときはしませんか?

答えて

3

私はこれがコンパイラの問題ではないと思っています。それ自体はです。整数値は決してnullではありませんが、それらを同一化する考えは無効ではありません。それは常にfalseを返す有効な関数です。コンパイラは知っています。コード

bool oneIsNull = 1 == null; 

コンパイルが、コンパイラの警告を与える:The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type '<null>'

コンパイラのエラーを元に戻したい場合は、プロジェクトのプロパティに移動し、このエラーの「警告をエラーとして処理する」をオンにすると、ビルド中断の問題として再度表示されます。

1

コンパイラは、null値ではない型とnullを比較すると、警告が生成されます。あなたの警告レベルが低すぎるかもしれませんが、これは最近のバージョンで変更されました(私は.net 3.5でしかできませんでした)。

3

奇数は... .NET 3.5をターゲット、VS2008でこれをコンパイル:

static int F() 
    { 
     return 42; 
    } 

    static void Main(string[] args) 
    { 
     int i = F(); 

     if (i == null) 
     { 
     } 
    } 

を私はコンパイラ警告

warning CS0472: The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type 'int?' 

を取得し、それは以下のILを生成...これはおそらく、JIT最適化されます

L_0001: call int32 ConsoleApplication1.Program::F() 
    L_0006: stloc.0 
    L_0007: ldc.i4.0 
    L_0008: ldc.i4.0 
    L_0009: ceq 
    L_000b: stloc.1 
    L_000c: br.s L_000e 

コードスニペットを投稿できますか?

+0

コンパイラは、1 == 2と同じように、真ではないことを正しく認識します。 intがintに暗黙的にキャストできることを知るには十分にスマートですか?そしてそのint? nullと比較することができます。私はオプティマイザがブロック全体を取り除くのに十分スマートであると思う。 – Keith

0

警告は新しく(私は3.5だと思います) - エラーは私が1 == 2を行った場合と同じです。

完全な3.5の最適化では、完全なステートメントが削除されると思うのですが、それは決して真実ではない評価では賢明です。

私は1==2をコンパイルしたいと思うかもしれませんが(私が他の何かをテストしている間に機能ブロックをオフにする)、私は1==nullを望ましくありません。

0

型が互換性がないため(値型を決してnullにすることはできません)、コンパイル時エラーである必要があります。それはそれほど悲しいことではありません。

+0

全体の質問を読んで、なぜそれが起こるか説明します。問題は、特殊なケースとして扱うことができない理由です。 – Keith

+0

私が「すべき」と言うのは、道徳的な命令があることを意味します。それは私がコンパイラがやるべきことではありません。あなたが説明した理論的根拠は、それほど魅力的ではありません。これは静的コンパイルの失敗にする必要があります。 – DrPizza

1

2.0フレームワークでは、null値型が導入されました。リテラル定数 "1"は決してnullにはなりませんが、基になる型(int)はNullable int型にキャストできます。私の推測では、たとえリテラル定数であっても、コンパイラはint型がnullableではないと仮定することができなくなります。

警告1タイプ 'int'の値が 'int'タイプの値と決して等しくないので、式の結果は常に 'false'です。

+0

私が言ったように - コンパイラはintがintに暗黙的にキャストできることを知っていますか? int? nullと比較することができます。 警告は決して真実でない比較のための一般的なものです。 1 == 2は同じ警告をスローします。 – Keith

関連する問題