2010-11-17 8 views
11

Come programmatore mi sarei aspettato che questo generasse un'eccezione. C'è una ragione per cui considera null come ""?C# aggiunta stringa + null non genera un errore?

string s = "hello"; 
string t = null; 

Console.WriteLine(s + t); 

uscita:

ciao

solo sottolineare la mia domanda, sai perché la decisione di trasformare nulla in String.Empty è stata fatta? Mi aspettavo che venisse aggiunta una stringa, ma c'era un problema più indietro in cui non si stava recuperando correttamente e tornava con null. Il problema è passato inosservato!

Ecco un pseudocodice del motivo per cui penso che sia male (e perché sono rimasto scioccato di scoprire nessun errore):

Si può supporre che sovraccaricato ToString di dare il nome della persona o dettagli su di loro.

Person p = PersonDatabase.GetForName("Jimmy Gibbs"); 

Console.WriteLine("Name is: " + p.ToString()); 

genera un'eccezione perché p è nullo

String p = PersonDatabase.GetForName("Jimmy Gibbs").Name; 

Console.WriteLine("Name is: " + p); 

non genera un'eccezione, anche se p è nullo (si tratta come "").

(Se si vuole essere pignoli e dire che non sarò in grado di ottenere Name come GetforName sarà nullo, penso come questo :)

String p = PersonDatabase.GetNameFromID(1234); // Returns a string or null if not found 

Console.WriteLine("Name is: " + p); 

(Se si utilizza questo valore in un lista o array finirai con una voce vuota che è ciò che ha rotto per me, stava creando javascript e cercando di ottenere l'elemento per ID di "")

+2

WoW e + null in maiuscolo la prima lettera che è un Plus :) – Bolu

+0

Posso solo speculare sul perché, ma un argomento a favore sarebbe quello di ridurre la possibilità di confondere gli sviluppatori inesperti, che sono abituati a pensare a null le eccezioni sono il risultato del dereferenziamento; averli causati dagli operatori potrebbe essere non intuitivo. Non è una buona argomentazione, secondo me, ma sarebbe in linea con il principio della meno sorpresa (se non aggiungi nulla a qualcosa, ti aspetti ancora di avere qualcosa). –

+0

Se è possibile utilizzare string t = null, si dovrebbe essere in grado di utilizzare anche altri operatori con null. – Bolu

risposta

6

L'operatore + viene emesso come string.Concat nell'IL risultante.

s + t = string.Concat(s, t) 

e quando guardando l'attuazione controlla se gli argomenti sono nulli e restituisce string.Empty:

smontato con riflettore:

[SecuritySafeCritical] 
public static string Concat(string str0, string str1) 
{ 
    if (IsNullOrEmpty(str0)) 
    { 
     if (IsNullOrEmpty(str1)) 
     { 
      return Empty; 
     } 
     return str1; 
    } 
    if (IsNullOrEmpty(str1)) 
    { 
     return str0; 
    } 
    int length = str0.Length; 
    string dest = FastAllocateString(length + str1.Length); 
    FillStringChecked(dest, 0, str0); 
    FillStringChecked(dest, length, str1); 
    return dest; 
} 
+1

Sai perché? Abbiamo avuto un brutto bug come risultato di ciò che è passato inosservato. – NibblyPig

+0

Questo è documentato: http://msdn.microsoft.com/en-us/library/a6d350wd.aspx (Una stringa vuota viene utilizzata al posto di qualsiasi argomento nullo). –

18

Dal C# Language Specification:

7.8.4 Operatore addizionale

concatenazione delle stringhe:

operatore stringa + (stringa x, stringa y); operatore stringa + (stringa x, oggetto y); operatore stringa + (oggetto x, stringa y);

Questi sovraccarichi dell'operatore binario + eseguono concatenazione di stringhe. Se un operando di concatenazione di stringhe è nullo, una stringa vuota è sostituita. Altrimenti, qualsiasi argomento non stringa viene convertito nella sua rappresentazione stringa invocando il metodo virtuale ToString ereditato dall'oggetto tipo . Se ToString restituisce null, viene sostituita una stringa vuota .

+2

Perché è una buona idea? – NibblyPig

+2

@ SLC Mi chiedo se abbia a che fare con il fatto che le stringhe sono tipi di riferimento ma si comportano come tipi di valore in molti modi (perché sono immutabili). Quindi, se si comporta in questo modo (quando si utilizza l'operatore +) si adatta a questo concetto. –

0

Gli operatori definiti dall'utente sono solo metodi statici e, naturalmente, possono accettare i parametri null. Questo è ad esempio molto utile per i delegati.

Quindi la stringa che accetta null non è una decisione tecnica ma di progettazione. Ed è probabilmente a volte utile trattare "null" poiché un sacco di codice utente li tratta allo stesso modo.

0

Se ho un'arancia e ne aggiungo un'altra arancione, ora ho due arance.

Se ho un'arancia e non aggiungo NULLA, ho ancora un'arancia.

Aggiungo NULL a una stringa e ottenere la stringa originale sembra perfettamente intuitiva e semantica. NullReferenceExceptions deve essere riservato per l'accesso alle proprietà o ai metodi di istanza su istanze che non esistono, ad es.

string myString = null; 
string lowerCaseString = myString.ToLower(); 

Sarebbe comprensibilmente gettare un NullReferenceException perché sto cercando di accedere al ToLower) metodo di istanza (su un riferimento che non esiste quindi Null Riferimento eccezione (es. C'è una cosa sulla pila, ma niente sull'Heap).

Avere operazioni di concatenazione di stringa NULL generano eccezioni significherebbe tonnellate di controlli di codice NULL in più difensivi quando si gestiscono stringhe, che sono fastidiose. Ci dispiace, ma sono d'accordo con come C# .NET gestisce questo. Non fa lo stesso Java?


Se si desidera controllare se una stringa contiene un valore quindi usare String.IsNullOrEmpty(myString); o String.IsNullOrWhitespace(myString); (solo in .NET 4.0)

-2

In realtà questo è il modo in stringhe sono rappresentate .... niente di sbagliato c'è. null viene utilizzato come carattere di terminazione.

Ad esempio:

stringa di un: "blahblah [null]" Quindi, qualunque legge la stringa sa di fermarsi a nulla.

quindi quando si crea una stringa come questa: stringa b: "[null]" è perfettamente valida.

Ora, non ci sono caratteri prima di null. così quando il tuo programma inizia a leggere la stringa incontra un valore nullo (perfettamente valido) e si ferma .... quindi ... stringa vuota !!

+2

acctually per C# questo è tecnicamente scorretto, credo. In c sono terminati con null, in C# il CLR mantiene un conteggio di quanti byte utilizza la stringa e la sua posizione. –

+2

Non solo questo non è il modo in cui C# memorizza le stringhe, ma l'intera spiegazione anche per C è piuttosto scorretta, confondendo la rappresentazione di 'NULL' /' null' per _ "puntatori" _ in linguaggi come C/C++/C# con il ASCII ** nul ** _character_, ''\ 0''. – JonBrave

1

Quando si prende in considerazione la decisione di progettazione che è stata presa, dovremmo guardare non solo all'operatore più per le stringhe, ma anche a classi e metodi correlati, ad es. String.Concat(String, String) e StringBuilder.Append(String). Queste classi fanno parte di Base Class Library che è ampiamente utilizzato in altri linguaggi (ad esempio Visual Basic e F #).

Dal punto di vista della progettazione di linguaggio e piattaforma, tutti questi metodi devono comportarsi in una fazione coerente (ad esempio, trattare null allo stesso modo). Vedo tre possibili opzioni:

  • eccezione del tiro

    Si tratta di una soluzione di "sicuro" in quanto non è chiaro cosa fare con nulla. Come compromesso, richiederebbe uno stile di programmazione più difensivo e un codice più dettagliato.

  • Utilizzare una rappresentazione per null ad es. <null>, null o [null] (stile Java)

    Questo è un risultato che ci si aspettava. Non è chiaro il motivo per cui ciò dovrebbe accadere e come esattamente dovrebbe essere rappresentato null.

  • Treat nullo nello stesso modo come stringa vuota (NET-stile)

    L'idea è quella rappresentazione testuale nullo (cioè un oggetto che manca) è una stringa vuota. In tal caso, un programmatore può sfruttare questo comportamento e scrivere un codice più breve. D'altra parte, può nascondere bug.

Alcune decisioni dovevano essere prese e penso che non ci sia una scelta ovvia. Il comportamento previsto in C# e altri linguaggi .NET è chiaramente documentato ed è coerente con tutti i metodi che trattano la concatenazione.

Problemi correlati