2012-05-17 9 views
5

Ho avuto questa discussione interessante oggi con un collega. Stavamo discutendo di due pezzi di codice in C#.Invia un valore null a qualcosa?

Snippet di codice 1:

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

Snippet di codice 2:

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

domanda è: si tratta di una buona pratica di gettare nulla in un lungo annullabile? O preferiresti usare la tradizionale istruzione if per evitare di trasmettere a lungo nulla null.

+1

Bene il cast è per l'operatore condizionale che si utilizza, ha bisogno del tipo di restituzione dei rami per essere simile e snippet2 è errore del compilatore è necessario che sia 'lungo? variable1' – V4Vendetta

+0

Come ha detto V4Vendetta, nel tuo secondo frammento i tuoi tipi lh e rh sono diversi. –

+0

In snippet1, 'variable1' esiste solo all'interno dell'ambito' if'. – comecme

risposta

15

Le espressioni (type?)null, default(type?) e new Nullable<type>() finiscono per essere compilati negli stessi codici operativi:

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

è trasformato 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> 

In altre parole, se si sta lavorando con i tipi nullable, siete liberi di utilizzare qualsiasi versione vi piace di più. Si noti tuttavia che si dovrebbe cercare di evitare aritmetica con tipi nullable. Se si desidera restituire un valore nullable da un'espressione condizionale, entrambi i risultati possibili devono essere annullabili se uno di essi può essere nullo. In questo caso, qualsiasi altro modo potrebbe causare un'eccezione.

+0

Per completezza: l'espressione 'null as type?' è anche compilata nello stesso codice IL. Infatti, 'null' non deve essere esplicitato in modo esplicito se l'espressione circostante fornisce un valore nullo tipo context, ad es. 'condition? null: value as type?'. Anche il 'null' in quell'espressione viene compilato nella' nuova Nullable () 'IL codice. – Wormbo

1

preferisco non lanciare null valore (sembra strano per me):

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

Un'altra possibilità:

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)); 

E 'solo la questione di gusti. Penso che la prima opzione sia più leggibile di altre.

UPDATE: Si consideri inoltre scrivendo alcuni metodi di estensione per rendere il codice più chiaro:

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

     return reader.GetInt64(index); 
    } 
} 

In questo caso non si utilizza operatore ternario (senza casting per nullable), e la lettura dei valori dal lettore appare più abbastanza:

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

@lazyberezovsky Coz ​​you ** non è possibile convertire da null a long?** – V4Vendetta

+0

@ V4Vendetta Ho corretto questo errore prima del tuo primo commento –

+0

@lazyberezovsky ce l'hai ancora lassù '...? null: (lungo?) reader.GetInt64 (2) ':( – V4Vendetta

0

Snippet 2 vale la pena nel mio caso, come nel caso di null che ti capita 0, che è un valore del tutto valida per long

3

Invece di

(long?) null 

uso

default(long?) 

avrei refactoring sopra il codice come

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

Perché stai usando le seconde parentesi intorno a 'long?'? –

+0

typo in taglia copia incolla, thansk per indicarlo – Tilak

Problemi correlati