Nullable ToString ()


142

Vedo ovunque costruzioni come:

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

Perché non usare semplicemente:

string test = myVar.ToString();

Non è esattamente lo stesso? Almeno Reflector afferma che:

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

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


1
Non ho visto codice come questo :)
tymtam,

Risposte:


112

Hai ragione. Anche in questa domanda , viene suggerita la prima soluzione, mentre nessuno si accorge che ToString()fornisce già la risposta corretta.

Forse l'argomento per la soluzione più dettagliata è la leggibilità: quando invochi ToString()qualcosa che dovrebbe essere null, di solito ti aspetti un NullReferenceException, anche se qui non viene lanciato.


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

7
Anche se sono sicuro che non è quello che volevi dire, il riferimento non è effettivamente nullo qui. Nullable <T> è un tipo di valore. Questo è il motivo per cui la chiamata ToString()funziona senza NullReferenceExceptionessere lanciata.
Thorarin,

2
Se quella fosse la mentalità, ti aspetteresti .HasValuedi gettare ancora quell'eccezione.
Extragorey,

Un altro motivo per cui le persone usano la versione dettagliata potrebbe essere la parità con espressioni come myNullableDateTime.HasValue ? myNullableDateTime.Value.ToString("d") : nulldove è necessario l'oggetto non imballato per accedere al ToStringmetodo desiderato . Naturalmente, esiste anche una soluzione più concisa per questo:$"{myNullableDateTime:d}"
Extragorey,

14

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


@Andrew, d'accordo, perché le persone (come me) all'inizio pensano che genererà un'eccezione.
Nathan Koop,

1
Non avevo idea che questo fosse il comportamento. Avrei sicuramente pensato che qualsiasi costrutto che ritorna vero per (x == null) genererebbe anche una NullReferenceException se chiami x.ToString ().
Dan Bryant,

5

No, hai ragione, la versione più corta è la stessa di ciò che altre persone hanno fatto a questo proposito. L'altro costrutto che tendo a usare molto al posto del ternario con nullable è l'operatore a coalescenza nulla. che ti protegge anche dai null. Per ToString () non è necessario (come hai sottolineato) ma per i valori int predefiniti (ad esempio) funziona bene, ad esempio:

int page = currentPage ?? 1;

che ti consente di eseguire tutte le operazioni sui numeri interi sulla pagina senza prima controllare e richiedere esplicitamente null per il valore in currentPage (dove currentPage è un int? forse passato come parametro)


5

Lo so, molto tempo dopo era rilevante, ma ... sospetto sia perché per tipi nullable come int? il metodo .ToString () non consente di utilizzare stringhe di formato. Vedi Come posso formattare un DateTime nullable con ToString ()? . Forse nel codice originale, c'era una stringa di formato in .ToString (), o forse il programmatore aveva dimenticato che .ToString () senza la stringa di formato era ancora disponibile su tipi nullable.


3

potrebbe essere solo per seguire il modello? o non conoscono il backend. hai ragione il codice è esattamente lo stesso. puoi persino fare:

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

Potrebbe essere necessario percorrere la strada lunga se ToString () deve essere di cultura invariante, poiché nullable non ce l'ha nel loro menu.
Ε Г И І И О

1

int?è lo zucchero di sintassi che semplifica la dichiarazione di variabile nullable. È lo stesso di Nullable<int>.

Quindi, se dai un'occhiata all'implementazione del ToString()metodo per Nullable<T> (vedi sotto) , puoi notare che restituisce una stringa vuota nel caso in cui non abbia alcun valore.

public struct Nullable<T> where T : struct
{
    public override string ToString()
    {
      if (!this.hasValue)
        return "";
      return this.value.ToString();
    }
}

Cosa dice MSDN:

Metodo Nullable.ToString

Restituisce la rappresentazione testuale del valore dell'oggetto Nullable corrente se la proprietà HasValue è vera o una stringa vuota ("") se la proprietà HasValue è falsa.

Quindi il codice seguente stamperà una stringa vuota sulla console invece di generare ArgumentNullExceptionun'eccezione.

static void Main(string[] args)
{
    int? a = null;
    Console.WriteLine(a.ToString()); // Prints empty string to console.
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.