5

int例として使用していますが、これは .Net の任意の値型に適用されます

.Net 1 では、以下はコンパイラ例外をスローします。

int i = SomeFunctionThatReturnsInt();

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

現在(.Net 2または3.5で)その例外はなくなりました。

これがなぜなのか私は知っています:

int? j = null; //nullable int

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

問題は、 becauseint?が null 可能でありint、暗黙的に にキャストされるようになったことint?です。上記の構文はコンパイラの魔法です。本当に私たちはやっています:

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)

だから今、私i == nullたちが得るとき:

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

とにかくC#がこれを計算するためにコンパイラロジックを実行していることを考えると、のような絶対値を扱うときにそれを実行しないほどスマートになれないのはなぜnullですか?

4

6 に答える 6

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>'

したがって、コンパイラエラーを元に戻したい場合は、プロジェクトプロパティに移動し、このエラーに対して「警告をエラーとして扱う」をオンにすると、ビルドを壊す問題として再び表示されるようになります。

于 2008-09-15T13:18:08.973 に答える
3

奇妙な...これをVS2008でコンパイルし、.NET 3.5をターゲットにします:

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

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

于 2008-09-15T13:14:45.830 に答える
1

null 非許容型を null と比較すると、コンパイラは依然として警告を生成しますが、これは本来あるべき姿です。警告レベルが低すぎるか、これが最近のバージョンで変更された可能性があります (.net 3.5 でのみ変更しました)。

于 2008-09-15T13:13:40.793 に答える
1

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

警告 1 タイプ 'int' の値がタイプ 'int?' の 'null' と等しくなることはないため、式の結果は常に 'false' になります。

于 2008-09-15T14:19:26.563 に答える
0

警告は新しいものです(3.5だと思います)-エラーは私がやったのと同じです1 == 2、それは決して真実ではないことを見つけるのに十分賢いです。

3.5を完全に最適化すると、真の評価がなく非常に賢いので、ステートメント全体が削除されるのではないかと思います。

コンパイルしたい1==2場合もありますが(たとえば、他の何かをテストしているときに関数ブロックをオフにするため)、したくありません1==null

于 2008-09-15T13:48:07.777 に答える
0

型に互換性がないため (値の型が null になることはありません)、コンパイル時エラーになるはずです。そうでないのはとても悲しいことです。

于 2008-09-15T13:57:21.687 に答える