2009-07-10 22 views
17

non so quante volte innumerevoli ho dovuto scrivere il codice per convalidare argomenti stringa:C#: convalida Argomento: null/stringhe vuote

public RoomName(string name) 
{ 
    if (string.IsNullOrEmpty(name)) 
    { 
     throw new ArgumentException("Cannot be empty", "name"); 
    } 
} 

Esiste un modo per evitare questo? Esiste un attributo o un meccanismo di progettazione per contratto per evitare questo? Non c'è modo di dire:

public RoomName(NotNullOrEmptyString name) 
{ 

senza dover effettivamente creare quel tipo?

+0

È possibile trovare questo collegamento su [Convalida degli argomenti utilizzando attributi e metodo di intercettazione] (http://www.codinginstinct.com/2008/05/argument- validation-using-attributes.html) utile – Joe

risposta

7

È possibile farlo tramite l'iniezione di codice con attributi.

Un'altra opzione per risparmiare un po 'di tempo per la codifica, ma che ti dà ancora molto controllo, sarebbe usare qualcosa come CuttingEdge.Conditions. Questo fornisce un'interfaccia fluida per il controllo argomento, in modo da poter scrivere:

name.Requires().IsNotNull(); 
1

Anche se la questione è stata risolta qualche tempo fa, ho pensato lo stesso problema ultimamente. Contratti di codice formalizzati (con verifica o assegni automatici) sembrano essere una buona idea, ma in generale, la loro capacità di verifica è abbastanza limitata, e per controlli semplici come il controllo di stringa vuota o vuota, richiedono tanto codice (o più) rispetto agli assegni antiquati.

Ironia della sorte, la migliore risposta a mio parere per la stringa caso è infatti uno o due classi che avvolgono una stringa che è stato controllato per non essere nullo, vuoto o bianco-spazio, e passare questa istanza in giro:

public class NonEmptyString : IComparable<NonEmptyString>, ... 
{ 
    private readonly string _value; 

    public NonEmptyString(string value) 
    { 
     if (value == null) 
     { 
      throw new ArgumentNullException("value"); 
     } 
     if (value.Length == 0) 
     {     
      throw NewStringIsEmptyException("value"); 
     } 
     _value = value; 
    } 

    public string Value 
    { 
     get { return _value; } 
    } 

    ... 
} 

public class NonWhiteSpaceString : NonEmptyString 
{ 
    .... 
} 

Certo, passando intorno a questi casi non vi impedisce di dover controllare se essi stessi sono nulli, ma ha alcuni grandi vantaggi:

  • non c'è bisogno di controllare il vuoto o bianco- stringhe spaziali ancora e ancora, che possono essere soggette a errori nelle situazioni in cui la stringa è passato molto.
  • Come ho fatto nella mia implementazione, il controllo di null è qualcosa di diverso dal controllo di un valore vuoto (o valore di spazi bianchi), perché si vuole lanciare una specifica ArgumentNullException nel primo caso, e qualche ArgumentException nel secondo.
  • Segnala chiaramente il vincolo sul valore della stringa, proprio come ogni classe di wrapping deve fare. In effetti, se si dispone di una stringa che presenta vincoli e viene passata molto, consiglio sempre di racchiuderla in una classe che incapsula il controllo e mantiene il resto del codice fuori dai guai. Un buon esempio di ciò sono stringhe che devono soddisfare una certa espressione regolare. Tuttavia, sto deviando dalla domanda qui ...
+1

Penso che sia necessario aggiungere un po 'di tracciamento del nome del parametro alla soluzione. Questo perché la maggior parte troverebbe confuso se tu chiamassi 'frob (string foo, string bar)' con 'frob (null," un valore ")' e riceverai il messaggio di errore 'System.ArgumentNullException: Il valore non può essere nullo. Nome parametro: valore' invece di 'System.ArgumentNullException: il valore non può essere nullo. Nome del parametro: foo' –