Perché Convert.ToString (null) restituisce un valore diverso se si esegue il cast di null?


116
Convert.ToString(null)

ritorna

null

Come mi aspettavo.

Ma

Convert.ToString(null as object)

ritorna

""

Perché sono diversi?

Risposte:


143

Ci sono 2 sovraccarichi ToStringche entrano in gioco qui

Convert.ToString(object o);
Convert.ToString(string s);

Il compilatore C # tenta essenzialmente di scegliere l'overload più specifico che funzionerà con l'input. Un nullvalore è convertibile in qualsiasi tipo di riferimento. In questo caso stringè più specifico di objecte quindi verrà scelto come vincitore.

In null as objecthai consolidato il tipo di espressione come object. Ciò significa che non è più compatibile con l' stringoverload e il compilatore sceglie l' objectoverload poiché è l'unico compatibile rimanente.

I dettagli davvero complicati di come funziona questa interruzione del legame sono trattati nella sezione 7.4.3 delle specifiche del linguaggio C #.


15
Ok. Quindi usa un sovraccarico invece dell'altro. Ha senso. Ma entrambi i sovraccarichi non dovrebbero restituire la stessa cosa? +1 btw.
John MacIntyre,

2
@JohnMacIntyre - Dipende dal team di sviluppo e non dal compilatore.
JonH

8
@JohnMacIntyre Se guardi all'implementazione di Convert.ToString(string)questa è solo una funzione di identità mentre in Convert.ToString(object)realtà attraversa un percorso più difficile da seguire. A prima vista sarei d'accordo che dovrebbero restituire lo stesso, ma lo strato convertibile del BCL non è qualcosa su cui sono molto informato ed è possibile che ci sia una buona ragione per la differenza (sono scettico però)
JaredPar

Sono venuto qui cercando come convertire un oggetto null in una stringa null. La risposta per gli altri ricercatori è (string)null, o se ti (string)o
opponi

65

In seguito all'eccellente risposta di JaredPar sulla risoluzione del sovraccarico , la domanda rimane "perché Convert.ToString(string)restituisce null, ma Convert.ToString(object)restituisce string.Empty"?

E la risposta è ... perché la documentazione dicono così :

Convert.ToString (stringa) restituisce "l'istanza di stringa specificata; non viene eseguita alcuna conversione effettiva".

Convert.ToString (object) restituisce "la rappresentazione di stringa di value o String.Empty se value è null".

EDIT: Per quanto riguarda se si tratta di un "bug nelle specifiche", "progettazione API pessima", "perché è stato specificato in questo modo", ecc. è un grosso problema.

  1. System.Convertha metodi per convertire ogni tipo di base in se stesso . Questo è strano, poiché non è necessaria o possibile alcuna conversione, quindi i metodi finiscono per restituire solo il parametro. Convert.ToString(string)si comporta lo stesso. Presumo che siano qui per scenari di generazione di codice.
  2. Convert.ToString(object)ha 3 scelte una volta superato null. Genera, restituisce null o restituisce una stringa. Il lancio sarebbe dannoso, doppiamente supponendo che vengano utilizzati per il codice generato. La restituzione di null richiede che il chiamante esegua un controllo null: di nuovo, non è un'ottima scelta nel codice generato. Restituzione di una stringa Vuoto sembra una scelta ragionevole. Il resto si System.Convertoccupa di tipi di valore, che hanno un valore predefinito.
  3. È discutibile se restituire null sia più "corretto", ma string.Empty è decisamente più utilizzabile. Cambiare Convert.ToString(string)significa infrangere la regola "nessuna conversione effettiva". Poiché System.Convertè una classe di utilità statica, ogni metodo può essere logicamente trattato come se fosse il suo. Ci sono pochissimi scenari del mondo reale in cui questo comportamento dovrebbe essere "sorprendente", quindi lascia che l'usabilità prevalga sulla (possibile) correttezza.

È giusto dire che è un bug nelle specifiche?
John MacIntyre,

3
questo non risponde perché è così. Dire che si comporta in questo modo perché è documentato che si comporta in questo modo è tautologico.
CodesInChaos

2
@ JohnMacIntyre IMO è giusto dire che è un design API pessimo.
CodesInChaos

7
@CodeInChaos - non una tautologia, a meno che non si presuma che i documenti siano scritti sulla base di un comportamento osservabile dopo lo sviluppo del BCL. Sarebbe uno strano presupposto, credo. IOW, non è "documentato a comportarsi in questo modo", è "documentato che si comportano in questo modo." - vale a dire, è " determinato a comportarsi in questo modo".
Mark Brackett

8
Sposta
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.