Qual è la differenza tra String.Empty e “” (stringa vuota)?

In .NET, qual è la differenza tra String.Empty e "" , e sono intercambiabili, oppure esiste qualche riferimento di base o problemi di localizzazione attorno all’uguaglianza che String.Empty garantirà non sono un problema?

In .NET precedente alla versione 2.0, "" crea un object mentre string.Empty non crea alcun riferimento agli oggetti, il che rende string.Empty più efficiente.

Nella versione 2.0 e successive di .NET, tutte le occorrenze di "" riferiscono alla stessa stringa letterale, il che significa che "" è equivalente a .Empty , ma non altrettanto veloce di .Length == 0 .

.Length == 0 è l’opzione più veloce, ma. .Empty rende il codice leggermente più pulito.

Vedere le specifiche .NET per ulteriori informazioni .

qual è la differenza tra String.Empty e “” e sono intercambiabili

string.Empty è un campo di sola lettura mentre "" è una costante di tempo di compilazione. I luoghi in cui si comportano diversamente sono:

Valore predefinito del parametro in C # 4.0 o superiore

 void SomeMethod(int ID, string value = string.Empty) // Error: Default parameter value for 'value' must be a compile-time constant { //... implementation } 

Espressione del caso nell’istruzione switch

 string str = ""; switch(str) { case string.Empty: // Error: A constant value is expected. break; case "": break; } 

Argomenti degli attributi

 [Example(String.Empty)] // Error: An attribute argument must be a constant expression, typeof expression // or array creation expression of an attribute parameter type 

Le risposte precedenti erano corrette per .NET 1.1 (guarda la data del post che hanno collegato: 2003). A partire da .NET 2.0 e versioni successive, non c’è sostanzialmente alcuna differenza. Il JIT finirà comunque per fare riferimento allo stesso object sull’heap.

In base alle specifiche C #, sezione 2.4.4.5: http://msdn.microsoft.com/en-us/library/aa691090(VS.71).aspx

Ogni stringa letterale non comporta necessariamente una nuova istanza di stringa. Quando due o più valori letterali stringa equivalenti secondo l’operatore di uguaglianza stringa (Sezione 7.9.7) vengono visualizzati nello stesso assembly, questi valori letterali stringa si riferiscono alla stessa istanza stringa.

Qualcuno lo cita anche nei commenti del post di Brad Abram

In breve, il risultato pratico di “” rispetto a String.Empty è nullo. Alla fine la JIT lo scoprirà.

Ho scoperto, personalmente, che il JIT è molto più intelligente di me e quindi cerco di non diventare troppo intelligente con le ottimizzazioni del micro-compilatore come questo. La JIT si spiegherà per () cicli, rimuovendo codice ridondante, metodi in linea, ecc. Meglio e in tempi più appropriati di quanto io o il compilatore C # potremmo mai anticipare prima mano. Lascia che il JIT faccia il suo lavoro 🙂

String.Empty è un campo String.Empty mentre "" è un const . Ciò significa che non è ansible utilizzare String.Empty in un’istruzione switch perché non è una costante.

Un’altra differenza è che String.Empty genera un codice CIL più grande. Mentre il codice per il riferimento a “” e String.Empty ha la stessa lunghezza, il compilatore non ottimizza la concatenazione delle stringhe (vedere il post sul blog di Eric Lippert) per gli argomenti String.Empty. Le seguenti funzioni equivalenti

 string foo() { return "foo" + ""; } string bar() { return "bar" + string.Empty; } 

generare questo IL

 .method private hidebysig instance string foo() cil managed { .maxstack 8 L_0000: ldstr "foo" L_0005: ret } .method private hidebysig instance string bar() cil managed { .maxstack 8 L_0000: ldstr "bar" L_0005: ldsfld string [mscorlib]System.String::Empty L_000a: call string [mscorlib]System.String::Concat(string, string) L_000f: ret } 

Le risposte di cui sopra sono tecnicamente corrette, ma quello che potresti davvero voler usare, per la migliore leggibilità del codice e meno possibilità di eccezione è String.IsNullOrEmpty (s)

Usa String.Empty piuttosto che "" .

Questo è più per la velocità rispetto all’utilizzo della memoria, ma è un suggerimento utile. Il "" è un valore letterale, quindi funzionerà come un letterale: al primo utilizzo viene creato e per i seguenti usi viene restituito il riferimento. Solo una istanza di "" sarà archiviata nella memoria, non importa quante volte la usiamo! Non vedo penalità di memoria qui. Il problema è che ogni volta che viene utilizzato il "" , viene eseguito un ciclo di confronto per verificare se il "" è già nel pool interno. Dall’altro lato, String.Empty è un riferimento a un "" memorizzato nella zona di memoria di .NET Framework . String.Empty punta allo stesso indirizzo di memoria per le applicazioni VB.NET e C #. Allora perché cercare un riferimento ogni volta che hai bisogno di "" quando hai quel riferimento in String.Empty ?

Riferimento: String.Empty vs ""

String.Empty non crea un object mentre “” fa. La differenza, come sottolineato qui , è tuttavia banale.

Tutte le istanze di “” sono la stessa stringa letterale internata (o dovrebbero essere). Quindi non dovrai mai lanciare un nuovo object nell’heap ogni volta che usi “” ma semplicemente creando un riferimento allo stesso object internato. Detto questo, preferisco string.Empty. Penso che renda il codice più leggibile.

Tendo ad usare String.Empty piuttosto che "" per una ragione semplice, ma non ovvia: "" e "" NON sono uguali, il primo ha in realtà 16 caratteri di larghezza zero. Ovviamente nessuno sviluppatore competente sta per inserire e zero caratteri di larghezza nel loro codice, ma se entrano in esso, può essere un incubo di manutenzione.

Gli appunti:

  • Ho usato U + FEFF in questo esempio.

  • Non sei sicuro che SO mangi quei personaggi, ma provalo tu stesso con uno dei tanti caratteri a larghezza zero

  • Mi sono imbattuto in questo grazie a https://codegolf.stackexchange.com/

 string mystring = ""; ldstr "" 

ldstr un nuovo riferimento a un object letterale di stringa memorizzato nei metadati.

 string mystring = String.Empty; ldsfld string [mscorlib]System.String::Empty 

ldsfld il valore di un campo statico nello stack di valutazione

Tendo ad usare String.Empty invece di "" perché IMHO è più chiaro e meno VB-ish.

Venendo da questo punto di vista di Entity Framework: EF versioni 6.1.3 sembra trattare String.Empty e “” in modo diverso durante la convalida.

string.Empty viene considerato come valore null ai fini della convalida e genera un errore di convalida se viene utilizzato su un campo Obbligatorio (attribuito); dove “” passerà la convalida e non genererà l’errore.

Questo problema può essere risolto in EF 7+. Riferimento: https://github.com/aspnet/EntityFramework/issues/2610 ).

Modifica: [Obbligatorio (AllowEmptyStrings = true)] risolverà questo problema, permettendo a string.Empty di convalidare.

Poiché String.Empty non è una costante in fase di compilazione, non è ansible utilizzarlo come valore predefinito nella definizione della funzione.

 public void test(int i=0,string s="") { // Function Body } 

Tutti qui hanno dato qualche buon chiarimento teorico. Ho avuto un dubbio simile. Così ho provato una codifica di base su di esso. E ho trovato una differenza. Ecco la differenza.

 string str=null; Console.WriteLine(str.Length); // Exception(NullRefernceException) for pointing to null reference. string str = string.Empty; Console.WriteLine(str.Length); // 0 

Quindi sembra che “Null” significhi assolutamente nulla e “String.Empty” significa che contiene qualche tipo di valore, ma è vuoto.