string.Empty vs null. Quale usi?


85

Recentemente un collega di lavoro mi ha detto di non usare string.Emptyquando si imposta una variabile di stringa ma di usarla nullcome inquina lo stack?

Dice di non farlo

string myString=string.Empty; ma fallo string mystring=null;

Importa davvero? So che la stringa è un oggetto, quindi ha un senso.

So che è una domanda stupida, ma qual è la tua opinione?


1
Non sono del tutto sicuro del motivo per cui lo faresti ... puoi fornire un po 'più del codice di cui stavi discutendo come esempio?
stusmith

non c'è codice. Ho chiesto al mio collega di guardare qualcosa che stavo mettendo a punto e lui ha detto come regola generale "non usare string.empty" impostalo a null mentre va nello stack.Personalmente ho sempre usato string.Empty poiché l'ora in cui è uscito doveva essere la cosa giusta da usare invece di "".
user712923


Quello che voglio dire è ... string.Empty, ""e nullsono tutti valori costanti, ma sono tutti abbastanza "semplici" da non capire perché ne assegneresti uno a una variabile. Se hai bisogno di catturare una outvariabile, perché non usarla string myString;?
stusmith

8
Oggigiorno, gli argomenti su argomenti come questo che non sono incentrati sulla leggibilità e la semantica e si concentrano su assurde micro-ottimizzazioni sono deboli, nella migliore delle ipotesi. Usa quello che significa la cosa corretta per il tuo contesto. (ad esempio, se sai che qualcuno non ha un secondo nome, lo usi String.Empty; se non sai se qualcuno ha o meno un secondo nome, usi null). Quindi, una volta che hai il significato giusto, scrivi il codice in un modo chiaramente corretto e facilmente gestibile.
jason

Risposte:


111

nulle Emptysono molto diversi e non suggerisco di passare arbitrariamente da uno all'altro. Ma nessuno dei due ha alcun "costo" aggiuntivo, poiché Emptyè un unico riferimento fisso (puoi usarlo un numero qualsiasi di volte).

Non c'è "inquinamento" sullo stack causato da un ldsfld - questa preoccupazione è ... pazzesca. Il caricamento di a nullè probabilmente leggermente più economico, ma potrebbe causare eccezioni di riferimento nullo se non si sta attenti a controllare il valore.

Personalmente, non uso nessuno dei due ... Se voglio una stringa vuota, uso ""- semplice e ovvio. Interning significa che anche questo non ha overhead per utilizzo.


A livello IL, la differenza qui tra "" e Empty è solo ldstr vs ldsfld - ma entrambi danno lo stesso singolo riferimento a stringa interna. Inoltre, nelle versioni .NET più recenti, JIT ne ha intercettato direttamente, restituendo il riferimento a una stringa vuota senza eseguire effettivamente una ricerca di campo statico. Fondamentalmente, non c'è esattamente alcun motivo per preoccuparsi in entrambi i casi, tranne la leggibilità. Uso solo "".


5
@ user712923 se torna con delle preoccupazioni concrete, mi piacerebbe ascoltarle
Marc Gravell

4
@ Marc: ASAIK "" crea un oggetto dove string.Empty non è .. controlla questo e questo . Ha qualcosa a che fare con il pool di tirocinanti ...
Jalal ha detto il


1
+1 per l'utilizzo al ""posto di un codice boilerplate sei volte più lungo. Chi ha sostenuto questa assurdità ?! @Jalal che Brad Abrams distacco è seriamente superata e se il compilatore ancora non ottimizza questi due codici a fare lo stesso, allora vergogna su Microsoft! Ma non è nostro compito sistemare il loro lavoro. E infatti, non abbiamo bisogno di: Nel secondo collegamento, Lasse (nei commenti) ha confrontato gli output dell'assembly del confronto con entrambe le varianti: sono identici.
Konrad Rudolph

1
@ Konrad: Un esempio è ciò che accade quando si concatenano stringhe costanti: la classe stringa utilizza il pool interno, quindi quando crei una nuova stringa, la classe controlla se la stringa è già nel pool e poi se non la aggiunge al pool .. Per questo motivo "", quando cercherà nell'intero pool per verificare se è già presente o meno, e in questo modo quando si utilizza string.Empty;utilizzerà quel valore predefinito e la ricerca non esisterà più. la classe ha anche esposto questo metodo: string.Intern/IsInternedcontrolla questo
Jalal Said

35

Non "inquina lo stack", non c'è motivo tecnico ma c'è una grande differenza tra impostare una variabile su un riferimento a un oggetto (anche se è una stringa vuota) e null. Non sono la stessa cosa e dovrebbero essere usati in modi diversi.

nullva utilizzato per indicare l'assenza di dati, string.Empty(oppure "") per indicare la presenza di dati, appunto del testo vuoto. C'è un caso specifico in cui non sei sicuro di quale sia il più appropriato?

Modifica, aggiunti esempi:

  • Potresti usare string.Emptycome suffisso predefinito per il nome di una persona (la maggior parte delle persone non ha un dottorato di ricerca, ad esempio)

  • Potresti usare nullper un'opzione di configurazione che non è stata specificata nel file di configurazione. In questo caso, string.Emptysarebbe utilizzato se fosse presente l'opzione di configurazione, ma il valore configurato desiderato era una stringa vuota.


Non ho mai pensato in questo modo, devo ammetterlo.Dato quello che hai appena detto, ti dispiace farmi un esempio.So che la tua spiegazione è autoesplicativa ma comunque ... grazie
user712923

2
Bene, l'unico motivo per scegliere l'uno o l'altro è basato sul luogo in cui lo useresti. Ad esempio, usa string.Emptyo ""quando vuoi usare una stringa vuota e nullquando vuoi indicare che non ci sono dati. Potresti usare string.Emptycome suffisso predefinito per il nome di una persona (la maggior parte delle persone non ha un dottorato di ricerca, ad esempio) e nullper un'opzione di configurazione che non è stata specificata nel file di configurazione. In quel secondo caso, string.Emptysarebbe stato utilizzato se fosse presente l'opzione di configurazione, ma il valore configurato desiderato era una stringa vuota.
Kieren Johnstone

@Kieren Johnstone, se uno non ha il nome del suffisso, perché non nulldovrebbe indicare "nessun suffisso"?
OfirD

8

Sono diversi poiché altri hanno già risposto.

static void Main(string[] args)
{
    string s1 = null;
    string s2 = string.Empty;
    string s3 = "";
    Console.WriteLine(s1 == s2);
    Console.WriteLine(s1 == s3);
    Console.WriteLine(s2 == s3);
}

 results:
 false     - since null is different from string.empty
 false     - since null is different from ""
 true      - since "" is same as string.empty

Il problema con la gestione di stringhe vuote rispetto a stringhe null sta diventando un problema quando è necessario mantenerlo in un file flat o trasferirlo tramite comunicazioni, quindi trovo che potrebbe essere utile per altri che visitano questa pagina per dare una buona soluzione a quel particolare problema.

Allo scopo di salvare stringhe in un file o comunicazioni:
probabilmente vorrai convertire la stringa in byte.
una buona pratica che consiglio è di aggiungere 2 segmenti di byte di intestazione alla stringa convertita.

segmento 1 - meta info che viene memorizzata in 1 byte e descrive la lunghezza del segmento successivo.

segmento 2 - contiene la lunghezza della stringa da salvare.

esempio:
stringa "abcd" - per semplificare lo convertirò usando un codificatore ASCII e otterrò {65,66,67,68}.
calcolare il segmento 2 produrrà 4 - quindi 4 byte sono la lunghezza della stringa convertita.
calcolare il segmento 1 restituirà 1 - poiché è stato utilizzato solo 1 byte per contenere le informazioni sulla lunghezza delle informazioni sulla stringa convertita (che era 4, cioè se fosse 260 otterrei 2)

La nuova striscia di byte sarà ora {1,4,65,66,67,68} che può essere salvata in un file.

Il vantaggio rispetto all'argomento è che se avessi una stringa vuota da salvare otterrei dalla conversione un array vuoto di byte di lunghezza 0 e dopo aver calcolato i segmenti finirò per avere {1,0} che può essere salvato e successivamente caricato e interpretato di nuovo in una stringa vuota. D'altra parte, se avessi un valore nullo nella mia stringa, finirei per avere solo {0} come array di byte da salvare e di nuovo quando caricato può essere interpretato come nullo.

Ci sono più vantaggi come sapere quale sia la dimensione da caricare o accumulare se si frastagliano più corde.

Tornando all'argomento ... beh, inquinerà lo stack in quanto gli stessi principi descritti vengono utilizzati da qualsiasi sistema per differenziare i valori nulli da quelli vuoti .. quindi sì stringa. Vuoto richiede più memoria di null, anche se non lo farei chiamalo inquinamento .. è solo 1 byte in più.


1

È stato risposto a morte, ma null significa nessun valore, non inizializzato. string.Empty significa "" (una stringa vuota) come indicato su MSDN.

Il modo più sicuro per verificare la presenza di una stringa vuota o nulla è utilizzare string.IsNullOrEmpty.


-2

FWIW, ho scoperto che il missaggio ""e String.Emptynon funziona:

var a = "";
alert("a " + (a == "") + ", " + (a==String.Empty));   //Yields "a true, false"

var b = String.Empty;
alert("b " + (b == "") + ", " + (b == String.Empty)); //Yields "b false, true"

In particolare, se utilizzi $.trimper ottenere il valore di un campo di input DOM vuoto, quindi confrontalo con String.Empty, ottieni false. Non sono sicuro del motivo, ma eccoti. Ora uso solo ""ovunque per coerenza.


1
Sì. Questo è il motivo per cui dovremmo tutti rimanere nell'abitudine di controllare .Length==0o utilizzare.Compare()
zanlok

14
Questa domanda chiede di c # non js
Cole Johnson
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.