Warum ist integer == null
ein gültiger boolescher Ausdruck in C#, wenn integer
(Variable vom Typ int
) nicht nullfähig ist? (Ich bin nicht dagegen, in der Tat ich es mag, aber ich wusste nicht, dass es möglich war)Warum ist Integer == null ein gültiger boolescher Ausdruck in C#?
Antwort
Obwohl int
selbst ist nicht nullable, gibt es eine implizite Konvertierung in int?
, die ist nullable.
An diesem Punkt, wenn die Struktur einen Operator ==
mit dem gleichen Typ auf beiden Seiten deklariert, dann wird das aufgehoben, um mit NULL-Typen zu arbeiten.
So bedeutet dies nicht kompilieren:
public struct Foo {}
class Test
{
static void Main()
{
Foo x = new Foo();
if (x == null)
{
...
}
}
}
... aber wenn man Foo
einige Betreiber geben, es tut Kompilierung, und ohne eine Warnung:
public struct Foo
{
public static bool operator ==(Foo x, Foo y) { return true; }
public static bool operator !=(Foo x, Foo y) { return false; }
public override bool Equals(object x) { return false; }
public override int GetHashCode() { return 0; }
}
Der Betreiber Aufruf ist nicht in dem kompilierten Code enthalten, da der Compiler kennt, dass das RHS null ist.
So Code der folgenden Form (wo Foo
kann durch jede nicht-NULL festlegbare struct
ersetzt werden) hat eine der drei Ergebnisse mit dem MS C# 5 Compiler:
- CS0472 Warnung (zB mit
int
) - CS0019 Error (benutzerdefinierte Typen, die nicht überlasten
==
) - Saubere Zusammenstellung (benutzerdefinierte Typen, die
==
überlasten, einschließlichGuid
undDateTime
)
Es ist mir nicht klar, warum der Compiler einige "bekannte" Typen anders als normale Strukturen behandelt. EDIT: Wie von Eric in Kommentaren bemerkt, ist dies ein bekannter Fehler im C# -Compiler, der hoffentlich in Roslyn behoben wird.
Bah, bessere Antwort als meine ... –
Verdammt, das ist seltsam! Vielleicht sind Strukturen die Ausnahme? –
@ guillegr123: Ich versuche immer noch, es auszuarbeiten ... –
Wie Ed erwähnt gibt es eine Warnung, aber die Warnung verweist auf den Grund: int
kann int?
Auto-gegossen sein, und null
ist ein gültiger Wert für eine Variable vom Typ int?
.
Sie erhalten eine Warnung, etwas in der Art von "Ausdruck ist immer falsch". Warum es * erlaubt * ist, d. H. Es führt nicht zu einem Kompilierzeitfehler ... Ich nehme an, es ist aus demselben Grund erlaubt; 'while (true)' –
Der C# -Compiler wird diese Zeit bei der Kompilierung auf "false" setzen, wenn er im Freigabemodus kompiliert wird (ein 'ldc.i4.0 'landet in IL). – vcsjones
mögliches Duplikat von [C# okay, wenn Werttypen mit null verglichen werden] (http://stackoverflow.com/questions/1972262/c-sharp-okay-with-comparing-value-types-to-null) –