Frage

Ich verwende int als Beispiel, aber das gilt für jeden Werttyp in .NET

In .Net 1 die folgenden würde eine Compiler Ausnahme auslösen:

int i = SomeFunctionThatReturnsInt();

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

Jetzt (in .Net 2 oder 3.5), die Ausnahme ist gegangen.

Ich weiß, warum das so ist:

int? j = null; //nullable int

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

Das Problem ist, dass, weil int? NULL-Werte zulässt und int nun eine implizite Umwandlung zu int? hat. Die Syntax oben ist Compiler Magie. Wirklich wir tun:

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)

So, jetzt, wenn wir i == null tun wir bekommen:

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

Da C # Compiler Logik tut dies berechnen sowieso, warum kann es nicht klug genug sein, um es nicht zu tun, wenn sie mit absoluten Werten wie null zu tun?

War es hilfreich?

Lösung

Ich glaube nicht, das ein Problem mit dem Compiler ist per se ; ein Integer-Wert ist nie null, aber die Idee, sie gleichzusetzen ist nicht ungültig; es ist eine gültige Funktion, die immer false zurück. Und der Compiler weiß; der Code

bool oneIsNull = 1 == null;

kompiliert, sondern gibt eine Compiler-Warnung:. The result of the expression is always 'false' since a value of type 'int' is never equal to 'null' of type '<null>'

Wenn Sie also den Compilerfehler zurück wollen, gehen Sie zu den Projekteigenschaften und schalten Sie ‚Warnungen als Fehler behandeln‘ für diesen Fehler, und Sie werden beginnen, sie als Build-breaking Probleme wieder zu sehen.

Andere Tipps

Odd ... Kompilieren dies mit VS2008, Targeting .NET 3.5:

static int F()
{
    return 42;
}

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

    if (i == null)
    {
    }
}

Ich erhalte eine Compiler-Warnung

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

Und es generiert die folgende IL ..., die vermutlich die JIT wird optimieren entfernt

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

Können Sie einen Code-Schnipsel einfügen?

Compiler erzeugt noch Warnung, wenn Sie nicht-Nullable Type vergleichen auf null, die genau so, wie es sein sollte. Kann Ihre Warnstufe zu niedrig ist oder dies wurde in der letzten Versionen (ich habe nur, dass in .net 3.5).

geändert

Der 2.0-Framework eingeführt, um den Nullable-Wertetyp. Auch wenn die wörtliche Konstante „1“ nie Null sein kann, die ihr zugrunde liegenden Typ (int) kann nun auf einen Nullable int-Typ umgewandelt werden. Meine Vermutung ist, dass der Compiler kann nicht mehr davon ausgehen, dass int-Typen sind keine Nullwerte enthalten, auch wenn es sich um eine wörtliche konstant ist. Ich habe eine Warnung erhalten, wenn 2,0 Kompilieren:

Warnung 1 Das Ergebnis des Ausdrucks ist immer ‚falsch‘, da ein Wert vom Typ ‚int‘ ist nie gleich ‚Null‘ vom Typ ‚int?‘

Die Warnung ist neu (3.5 glaube ich) - der Fehler ist das gleiche, als ob ich 1 == 2 getan hatte, die es klug genug ist, als nie wahr zu erkennen

.

Ich vermute, dass mit voller 3.5 Optimierungen der ganze Aussage wird nur abgezogen werden, wie es mit nie wahr Evaluationen ziemlich klug ist.

Während ich vielleicht will 1==2 kompilieren (einen Funktionsblock auszuschalten, während ich etwas anderes zum Beispiel testen) Ich mag nicht 1==null an.

Es sollte ein Fehler bei der Kompilierung sein, weil die Typen nicht kompatibel sind (Werttypen niemals null sein). Es ist ziemlich traurig, dass es nicht ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top