2009-11-06 12 views
14

Dopo un incidente sul posto di lavoro dove ho abusato String.IsNullOrEmpty con una variabile di sessione, un collega collega di mine ora rifiuta di accettare il mio utilizzo di String.IsNullOrEmpty. Dopo alcune ricerche, a quanto pare c'è un bug elencato per IsNullOrEmpty su MSDN (link) (vedi nota in fondo):C# String.IsNullOrEmpty: buono o cattivo?

A partire dal 4 Aprile 2006, c'è un bug (possibile nel JIT) che fa questo metodo fallisce quando le ottimizzazioni sono attivate. È noto che influisce sia su C# sia su VB.

Ulteriori informazioni possono essere trovate qui (link). Microsoft il bug è "apparentemente" fisso post-Orche, ma sfortunatamente il mio datore di lavoro usa ancora VS2005. Ma se il problema è stato risolto nel 2008+ così sia. Va bene con me.

Mentre il rifiuto del mio collega del mio codice con IsNullOrEmpty per me è cieca ignoranza (IMO) di certo non può dirmi perché non da usare in altro modo che l'uso improprio con la variabile di sessione. Ho usato IsNullOrEmpty su tutto il nostro codice senza problemi di sorta. Personalmente, lo trovo molto più leggibile oltre a fare due cose in una dichiarazione.

Dopo googling per pareri in materia, ho i siti che prendono il pro/con posizione trovato. Ecco alcuni dei siti che ho letto su questo:

https://blog.rthand.com/post/2006/06/22/1063.aspx

http://www.omegacoder.com/?p=105

Un sito (http://dotnetperls.com/isnullorempty) riassume il metodo (IMHO) piuttosto bene:

Qui sembrava che IsNullOrEmpty metodo del tipo stringa, che ci fornisce un metodo efficiente relativamente buona e di verificare se unLa stringapuò essere salvata o utilizzata. Tuttavia, per le prestazioni, potrebbe essere preferibile eseguire utilizzando controlli null manuali. Le stringhe vuote possono essere testati in altri modi, e mia ricerca qui dimostra che il controllo lunghezza è più veloce.

Assumendo che la correzione di bug è a posto (e funziona correttamente) in VS2008/2010/ecc., Non v'è alcun motivo per non utilizzare String.IsNullOrEmpty con VS2005 e oltre? Mi rendo conto che questo può sembrare un po 'eccessivo rispetto a un metodo così sciocco, ma mi piacerebbe sapere se c'è più dietro le quinte e se qualcuno ha spiegazioni alternative.

risposta

24

Questo problema è stato risolto in .NET 2.0 SP1. Non c'è motivo di evitarlo ora.

Se stai usando .NET 2, si dovrebbe avere SP1 per molte altre ragioni in ogni modo - non vedo alcuna ragione per evitare questo per un bug che non esiste più.

+0

Grazie, cercherò di ottenere il service pack se non è già installato. Non sono sicuro di tutti i cerchi che dovrò saltare, ma in ogni caso, dovremmo eseguire l'ultimo service pack sul nostro server web a prescindere. Grazie! – osij2is

0

Se si è rotto nella versione, allora è banale di avere solo un metodo statico che farà il controllo, quindi basta fare:

public static bool isNull(String s) { 
    return s == null || s.trim().length == 0; 
} 

Inutile entrare in un grande problema su qualcosa che dovrebbe essere relativamente facile da risolvere.

Non è necessario cambiarlo ovunque, anche se è possibile eseguire una sostituzione globale di un metodo statico con un altro.

+0

Non c'è motivo di duplicare la funzionalità del framework. Questo è un bug corretto in .net 2.0sp1 - perché evitarlo adesso? –

+0

Grazie, sì sono d'accordo. Non c'è bisogno di entrare in una cosa importante per qualcosa di così banale, ma fintanto che è/è stato patchato non sono riuscito a trovare un motivo per * non * usarlo. Grazie per il codice di sostituzione. Posso implementarlo. – osij2is

+0

@Reed Copsey - Se sono interessati da questo, potrebbero non essere aggiornati a .NET2sp1. Certo, dovrebbero aggiornarsi, ma se non hanno poi, piuttosto che lottare per qualcosa di abbastanza banale, basta aggirarlo. –

4

si potrebbe scrivere uno unit test che passa una stringa vuota e uno che passa una stringa nulla per testare questa roba, ed eseguirlo in VS2005 e dopo nel 2008 e vedere cosa è successo

+0

Sfortunatamente, il mio attuale datore di lavoro non implementa realmente i test unitari. Per non dire che non vorrei saltare all'occasione ma grazie per l'idea. Forse è solo un altro motivo per cui posso dare al management che dovremmo * essere unit test per cominciare. – osij2is

2

In tale relazione bug nel link you include it states:

Questo bug è stato risolto nel Service Pack 1 (SP1) di Microsoft .NET Framework 2.0.

Poiché questo è il caso, non importa se si utilizza VS 2005 fino a quando SP1 per .NET 2 è installato.

Per quanto riguarda se usarlo o meno, dai un'occhiata a questo post by CodingHorror.

1

io sono abbastanza sicuro che è stato fissato sulla SP1, ma in ogni caso è possibile creare il proprio nullo o metodo vuoto :)

1

Come con qualsiasi lingua o parte di esso, è tutto di conoscere i pro/contro e facendo un decisione istruita basata su quella informazione. A PARER MIO.

+0

"... si tratta di conoscere i pro/contro e prendere una decisione istruita basata su tali informazioni." - Non è quello * perché * sto chiedendo qui? Per * prendere * e * educato * decisione? – osij2is

+0

@ osij2is - il mio commento non voleva assolutamente insultare. altri avevano già dichiarato che il bug era stato corretto, quindi non sentivo il bisogno di ripetere la risposta. Stavo semplicemente mettendo la mia prospettiva sulle differenze di opinione tra te e il tuo collega. se ora sai che la soluzione è perfettamente accettabile, ora hai l'argomento per il motivo per cui va bene .... IMHO :) – jaywon

3

Usiamo un metodo di estensione per string.IsNullOrEmpty:

public static bool IsNullOrEmpty(this string target) 
{ 
    return string.IsNullOrEmpty(target); 
} 

Usando questo approccio, anche se fosse rotto in qualche versione precedente, un bugfix è solo una riga di codice.

E il valore aggiunto di essere in grado di utilizzare il metodo su un'istanza stringa che potrebbe essere nullo:

string myString = null; 
if (myString.IsNullOrEmpty()) 
{ 
    // Still works 
} 
+0

VS2005 non funziona con le estensioni. Io tendo ad usare un'estensione me stesso solo perché trovo più naturale scrivere. –

+0

Non penso che VS2005 sia il problema. Sta usando la versione del framework .NET 2.0 pre SP1. Sono stati aggiunti i metodi di estensione C# 3.0, ma è perfettamente possibile utilizzarli nella libreria di framework 2.0 con una piccola modifica: http://geekswithblogs.net/robp/archive/2007/12/20/using-extension-methods- in-.net-2.0-con-visual-studio-2008.aspx –

+0

Non avevo idea (fino ad ora) che i metodi di estensione possano essere richiamati con successo quando l'istanza è nullo. –

5

Ho sentito parlare di quel bug prima, e da quello che ho potuto capire che non si verifica mai in qualsiasi codice reale, solo nel codice come nell'esempio che in realtà non fa nulla. Inoltre, il bug non è con il metodo IsNullOrEmpty stesso, quindi si verificherà indipendentemente da come si controlla la stringa.

Se il metodo esegue esattamente ciò che si desidera, è necessario utilizzarlo. Tuttavia, non dovresti usarlo in ogni situazione per controllare una stringa vuota. A volte vuoi solo controllare se la stringa è vuota e non se è nulla.

Se la variabile stringa è nulla, questo sarà solo saltare il blocco di codice:

if (!String.IsNullOrEmpty(str)) { ... } 

Se la variabile stringa è nulla, ciò causerà un'eccezione:

if (str.Length > 0) { ... } 

Se la variabile è non supposto essere nullo, probabilmente si desidera l'eccezione al posto del codice che considera il valore nullo come una stringa vuota.Se qualcosa non va, lo vuoi catturare il prima possibile, perché sarà più difficile rintracciare il problema alla fonte più a lungo l'eccezione deriverà dalla causa.

+0

Di conseguenza, perché sempre * preferisco * il metodo IsNullOrEmpty. Due azioni in un semplice passaggio. Quando si tratta di stringhe, trovo che la maggior parte delle persone tende a codificare l'una o l'altra (vuota contro nulla) ma raramente entrambe. Preferisco controllare sia vuoto che nullo se non ho molta esperienza con una particolare applicazione o impianto. – osij2is

+0

@ osij2is: Considera anche la semantica del codice ... Se usi IsNullOrEmpty significa che ti aspetti che il riferimento sia nullo a volte, e se il riferimento non dovrebbe mai essere nullo, il controllo per esso rende il codice confuso. – Guffa

+6

"Non si verifica mai nel codice reale" è una misura molto ottimistica. – peterchen

-5

Mi chiedo perché la gente usa string.Empty, non è una buona cosa, perché è una stringa inizializzata & questo concetto esiste solo in Net telaio in tutto il mondo questa è una stringa valida con len di 0 (DB server rendono molto chiaro destinction tra questo e si lamenterà se si ha il controllo logico di null ma si ottiene e si svuota la stringa). Penso che string.IsNullOrEmpty sia una delle 5 migliori pratiche/funzioni peggiori che io abbia mai visto, perché in qualche modo incoraggia/fa apparire ok le persone che iniziano le loro stringhe e può essere trattato come null. Questa funzione non dovrebbe mai essere stata aggiunta e penso che i ragazzi di .Net dovrebbero provare a eliminarlo :) Chi ha bisogno e vuol stringere comunque? Non l'ho mai usato a meno che non fosse necessario a causa di progetti esistenti.

+0

Considera di fornire dati quando possibile. Se esprimi opinioni, fornisci almeno una sorta di motivazione per renderla utile per gli altri. – IInspectable

1

Quando si implementa il controllo degli argomenti nelle API, di solito controllo ogni condizione separatamente e faccio eccezioni diverse: ArgumentNullException per un riferimento null o, in base all'API specifiche, ArgumentException per una stringa vuota. In questo caso, l'utilizzo di String.IsNullOrEmpty non consente di distinguere tra queste due condizioni di errore separate.

if (str == null) 
{ 
    throw new ArgumentNullException("str"); 
} 
if (str == string.Empty) 
{ 
    throw new ArgumentException("The string cannot be empty.", "str"); 
} 
Problemi correlati