Qual è il punto della proprietà string.Empty


35

Perché la proprietà è stata string foo = string.Emptyinclusa nel BCL? Sembra più dettagliato e non più chiaro del semplice utilizzo di una stringa vuota ( string foo = "")


6
Nitpick: non fa parte della lingua. Fa parte del BCL. VB.NET e F # possono usarlo, così come ogni altro linguaggio .NET.
Oded,

19
Perché altrimenti, non potresti fare cose cattive come typeof(string).GetField("Empty").SetValue(null, " ");;)
Mason Wheeler,

1
@MasonWheeler - Le gioie della riflessione. Per il vero male, hai bisogno di introspezione, eh?
Oded,

1
@MasonWheeler, +1. Oh dio, gli occhiali non fanno nulla!]
Machado,

1
@MasonWheeler Questo è puro, distillato male. Amo questo. Domanda se sei interessato: non sarebbe più sicuro (e decentemente performante) averlo scritto come public static string Empty { get { return string.Intern(""); } }?
Jesse C. Slicer,

Risposte:


55

Posso solo presumere qui:

string.Emptyè stato definito per la spiegazione - quando si inizializza una stringa, potrebbe non essere chiaro dal contesto che è ""stato effettivamente esplicitamente inteso come inizializzatore (anziché nullo dire " "o semplicemente come segnaposto durante il test). L'uso string.Emptyè una risposta definitiva a questo tipo di enigma.

Potrebbe anche essere un ritorno a C - una stringa vuota in C non è una stringa vuota. È un array di caratteri il cui primo carattere è null (quindi vuoto), che non è uguale a C #. Il mio punto qui è che in diverse lingue rappresenteresti una stringa vuota in diversi modi (e potrebbero avere significati diversi) - avendo una string.Emptypreclusione tale ambiguità.

A differenza di ciò che altri dicono su più oggetti - questo non è un problema poiché qualsiasi stringa letterale verrà internata durante la compilazione. Questo include il valore di string.Empty- "". Ogni volta che uno di questi viene ripetuto nel codice, l'oggetto verrà recuperato dal pool interno. Questo vale per il dominio dell'app .


5
+1 per essere l'unica risposta corretta finora.
psr

Alcune lingue potrebbero non avere nemmeno una stringa vuota letterale. Apparentemente, lo standard Pascal no.
dan04,

2
"una stringa vuota in C non è una stringa vuota" - ma se si scrive "", si ottiene {'\0'}, quindi non ci sarebbe alcuna differenza tra una stringa vuota letterale e qualche altro modo di definirla.
detenere il

14

Non sono sicuro al 100% delle fonti in cui ho imparato questi, ma alcuni dei punti per usarlo includono:

  • Ogni stringa in un assembly .NET è unica, quindi avere

    string foo = "";
    string bar = "";

    genera 2 stringhe nell'assieme di output poiché le stringhe sono immutabili. Avere entrambi i riferimenti string.Emptyriduce le dimensioni dell'assieme.

  • Esplicitazione. Quando incontri string.Emptyl'intento è chiaro che dovrebbe essere una stringa vuota. Ma se ti accorgi foo = ""che il programmatore ha rimosso il contenuto della stringa durante il test e ha dimenticato di aggiungerlo nuovamente, o dovrebbe essere così?

1
Sembrerebbe un comportamento strano mantenere in memoria due stringhe identiche. È in effetti quello che si fa?
Rig

36
In effetti, viene fatto il contrario: si chiama intern string (più precisamente, interning dei letterali). So per certo che è fatto in Java e Python, e sono abbastanza sicuro che lo sia anche nei linguaggi .NET. Naturalmente, può succedere solo nell'ambito di una singola unità di traduzione, quindi a meno che il caricatore dinamico unifichi tali dati, si può finire con una stringa vuota per file di programma. Ancora non tremendamente.

9
@delnan ha assolutamente ragione. ""/ string.Emptysono internati e verrà creato un solo oggetto.
Oded,

11
@Andy - Tutti i valori letterali delle stringhe sono internati in .NET. Non tutte le stringhe. Le stringhe create a livello di programmazione non vengono internate per impostazione predefinita. Vedi String.Intern su MSDN.
Oded,

3
@Oded et alia: in realtà nessuno di voi ha esattamente ragione. Innanzitutto, i valori letterali vengono internati all'interno di un assembly ma non necessariamente attraverso gli assembly . In secondo luogo, il fatto che la stringa vuota sia internamente o meno distribuita negli assiemi è un dettaglio di implementazione; alcune versioni del CLR lo fanno e altre no. C'è un link al mio articolo su questo fatto in una delle altre risposte; vederlo per i dettagli.
Eric Lippert,

2

Nessun oggetto verrà creato per string.Empty. L'uso ""creerà un oggetto che molto probabilmente verrà dal pool interno di stringhe.

In passato, le persone hanno eseguito test ed String.Emptyè leggermente più veloce, ma è una micro-ottimizzazione.

String.Empty è questo:

//The Empty constant holds the empty string value.   
//We need to call the String constructor so that the compiler doesn't mark 
//this as a literal.   
//Marking this as a literal would mean that it doesn't show up as a field 
//which we can access from native.  
public static readonly String Empty = ""; 

2
Quindi il tuo punto è ...?

1
Il punto è String.Empty è sostanzialmente una costante per "". Trova l'autore di String.cs per un significato più profondo. :)
Jon Raynor il

0

È una questione di ottimizzazione del consumo di memoria e di ottimizzazione del confronto delle stringhe. Ogni volta che si utilizza una stringa vuota nell'applicazione, si alloca un oggetto stringa contenente 0 caratteri. Per quanto riguarda il confronto delle stringhe, si può fare confrontando i riferimenti (puntatori) anziché i caratteri per carattere, il che è più veloce anche per le stringhe vuote.

Se si utilizza più volte la stessa stringa nell'applicazione, è possibile utilizzare lo stesso tipo di meccanismo chiamando String.Intern () con la stringa. Ma se stai usando ogni stringa una sola volta, allora userai solo più memoria.

Quindi String.Empty è solo un'ottimizzazione del caso speciale che vale la pena fare per la maggior parte delle applicazioni .Net, ecco perché è stato integrato nel BCL.

Per maggiori dettagli su questo argomento, consiglio vivamente di leggere il post sul blog di Eric Lippert .

Dovresti anche dare un'occhiata a questa documentazione a cui fa riferimento il suo post sul blog.


4
Link solo le risposte non danno buone risposte. Se Eric dovesse mai riorganizzare il suo blog questa risposta diventerà inutile. Si prega di riassumere il post qui quindi abbiamo tutte le informazioni a portata di mano.
ChrisF

7
@ChrisF: non riesco mai a riorganizzare il blog. Sarebbe un cambiamento decisivo, e tu sai cosa provo per quelli.
Eric Lippert,

1
@EricLippert - Mi rendo conto che non l'avresti mai fatto, tuttavia, solo le risposte dei link non sono buone risposte e dobbiamo incoraggiare le persone a rendersene conto.
ChrisF

3
@EricLippert Non si tratta solo di collegamenti effimeri. Si tratta anche di educazione nei confronti dei lettori qui, ci dovrebbe essere almeno abbastanza contenuto direttamente nella risposta in modo che i lettori possano formarsi un'opinione sul fatto di seguire il collegamento. E la risposta dovrebbe avere senso anche in una copia offline di SE.
Gilles 'SO- smetti di essere malvagio' il
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.