2012-05-17 4 views
5

Ich hatte heute eine interessante Diskussion mit einem Kollegen. Wir diskutierten zwei Codeabschnitte in C#.Wirf eine Null in etwas?

Code Snippet 1:

if(!reader.IsDBNull(2)) 
{ 
    long? variable1 = reader.GetInt64(2) 
} 

Code Snippet 2:

long variable1 = reader.IsDBNull(2) ? (long?) null : reader.GetInt64(2) 

Frage ist: ist es eine gute Praxis null in einen nullable lange zu werfen? Oder würden Sie lieber die traditionelle if-Anweisung verwenden, um zu vermeiden, dass null lang genug NULL ist.

+1

Nun, die Besetzung ist für den Conditional Operator, den Sie verwenden, muss der Rückgabetyp der Zweige ähnlich sein und snippet2 ist Compiler-Fehler Sie brauchen es zu "long"? variable1' – V4Vendetta

+0

Wie V4Vendetta sagte, sind in Ihrem zweiten Snippet Ihre lh- und rh-Typen unterschiedlich. –

+0

In snippet1 existiert 'variable1' nur innerhalb des Bereichs 'if's. – comecme

Antwort

15

Die Ausdrücke (type?)null, default(type?) und new Nullable<type>() am Ende kompiliert wird in die gleichen Opcodes Refactoring würde:

 long? x = (long?)null; 
     long? y = default(long?); 
     long? z = new Nullable<long>(); 

wird verwandelte sich in:

IL_0001: ldloca.s x 
    IL_0003: initobj valuetype [mscorlib]System.Nullable`1<int64> 
    IL_0009: ldloca.s y 
    IL_000b: initobj valuetype [mscorlib]System.Nullable`1<int64> 
    IL_0011: ldloca.s z 
    IL_0013: initobj valuetype [mscorlib]System.Nullable`1<int64> 

Mit anderen Worten, wenn Sie mit Nullable-Typen arbeiten, Sie kostenlos zu benutzen sind je nachdem, welche Version Sie am besten gefällt. Beachten Sie jedoch, dass Sie versuchen sollten, Arithmetik mit nullbaren Typen zu vermeiden. Wenn Sie einen nullfähigen Wert aus einem bedingten Ausdruck zurückgeben möchten, müssen beide möglichen Ergebnisse nullwertfähig sein, wenn einer von ihnen null sein kann. Jeder andere Weg könnte in diesem Fall eine Ausnahme verursachen.

+0

Der Vollständigkeit halber: Der Ausdruck 'null as type?' wird ebenfalls in denselben IL-Code kompiliert. Tatsächlich muss 'null' nicht explizit deklariert werden, wenn der umgebende Ausdruck ein NULL-Zeichen liefert type context, zB 'condition? null: value als type?'. Das 'null' in diesem Ausdruck wird auch in das' new Nullable () 'IL compiliert Code. – Wormbo

1

ziehe ich es nicht null Wert werfen (es mir seltsam aussieht):

long? variable1 = reader.IsDBNull(2) ? null : (long?)reader.GetInt64(2); 

Weitere Optionen:

long? variable1 = reader.IsDBNull(2) ? default(long?) : reader.GetInt64(2); 
long? variable1 = reader.IsDBNull(2) ? (long?)null : reader.GetInt64(2); 
long? variable1 = reader.IsDBNull(2) ? new Nullable<long>() : reader.GetInt64(2); 
long? variable1 = reader.IsDBNull(2) ? new long?() : reader.GetInt64(2); 
long? variable1 = reader.IsDBNull(2) ? null : new long?(reader.GetInt64(2)); 

Es ist nur die Frage des Geschmacks. Ich denke, die erste Option ist lesbarer als andere.

UPDATE: Stellen Sie sich auch einige Erweiterungsmethoden Schreiben Sie den Code deutlicher zu machen:

public static class DataReaderExtensions 
{ 
    public static long? GetNullableInt64(this IDataReader reader, int index) 
    { 
     if (reader.IsDBNull(index)) 
      return null; 

     return reader.GetInt64(index); 
    } 
} 

In diesem Fall, dass Sie nicht verwenden ternären Operator (kein Casting NULLABLE), und Lesewerte von Lesern mehr sehen recht:

long? variable1 = reader.GetNullableInt64(2); 
+0

@lazyberezovsky Coz ​​Sie ** kann nicht null zu lange konvertieren?** – V4Vendetta

+0

@ V4Vendetta Ich habe diesen Tippfehler vor deinem ersten Kommentar behoben –

+0

@lazyberezovsky hast du noch da oben '...? null: (lang?) reader.GetInt64 (2) ':( – V4Vendetta

0

Snippet 2 ist in meinem Fall wert, wie im Fall von null du wird 0 erhalten, die für long

ein vollständig gültigen Wert
3

Statt

(long?) null 

Verwendung

default(long?) 

ich über Code wie

long? variable1 = reader.IsDBNull(2) ? default(long?) : reader.GetInt64(2) 
+0

Warum benutzt du zweite Klammern um 'lang?'? –

+0

Tippfehler in copy copy paste, thansk für die Angabe – Tilak

Verwandte Themen