2010-03-15 16 views
121

Vedo ovunque costruzioni come:ToString Nullable()

int? myVar = null; 
string test = myVar.HasValue ? myVar.Value.ToString() : string.Empty; 

perché non utilizzare semplicemente:

string test = myVar.ToString(); 

Non è che esattamente la stessa cosa? Almeno Riflettore dice che:

public override string ToString() 
{ 
    if (!this.HasValue) 
    { 
    return ""; 
    } 
    return this.value.ToString(); 
} 

Quindi, è corretto (la versione più breve) o mi sto perdendo qualcosa?

+0

Non ho visto il codice come questo :) – mayu

risposta

97

Sei proprio corretto. Anche in this question, la soluzione precedente viene suggerita mentre nessuno nota che lo ToString() fornisce già la risposta corretta.

Forse l'argomento per la soluzione più prolisso è la leggibilità: Quando si chiama ToString() su qualcosa che è suppone essere null, di solito si aspetta un NullReferenceException, anche se qui non si butta.

+17

In realtà, almeno due persone hanno notato: Eric Lippert e Johannes Rössel. –

+7

Mentre sono sicuro che non è quello che intendevi, il riferimento non è effettivamente nullo qui. Nullable è un tipo di valore. Questo è il motivo per cui chiamare 'ToString()' funziona senza che venga lanciata alcuna 'NullReferenceException'. – Thorarin

14

Penso che molte persone abbiano tali controlli perché non è un comportamento naturale di un oggetto che può contenere valore nullo.

+0

@Andrew, d'accordo, perché la gente (come me) pensa in un primo momento che genererà un'eccezione. –

+0

Non avevo idea che questo fosse il comportamento. Sicuramente avrei pensato che qualsiasi costrutto che restituisce true per (x == null) genererebbe anche una NullReferenceException se si chiama x.ToString(). –

3

può essere è solo seguire lo schema? o non conoscono il back-end. hai ragione il codice è esattamente lo stesso. Si può anche fare:

int? i = null; 
i.ToString(); //No NullReferenceException 
+0

Potrebbe essere necessario prendere il percorso lungo se ToString() deve essere di cultura invariabile, poiché nullable non lo ha nel proprio menu. –

5

No, siete sulla strada giusta, la versione più breve è lo stesso di quello che altre persone hanno fatto in proposito. L'altro costrutto tendo ad usare molto invece del ternario con nullables è l'operatore coalescente null. che ti protegge anche da null. Per ToString() non è necessario (come lei ha sottolineato), ma per valori int predefiniti (per esempio) funziona bene, ad esempio:

int page = currentPage ?? 1; 

che ti permette di fare tutte le operazioni interi a pagina w/o prima in modo esplicito controllo nullo e la chiamata per il valore in currentPage (dove currentPage è un int? forse passato come un parametro)

5

Lo so, molto tempo dopo era rilevante, ma ... sospetto che lo sia perché per i tipi nullable come int? il metodo .ToString() non ti permette di usare le stringhe di formato. Vedi How can I format a nullable DateTime with ToString()?. Forse nel codice originale c'era una stringa di formato in .ToString(), o forse il coder aveva dimenticato che .ToString() senza la stringa di formato era ancora disponibile sui tipi nullable.