2011-12-19 10 views
5

Ho più variabili che ho impostato prima di creare un oggetto, voglio verificare se una di quelle variabili è nulla, se una variabile qualsiasi mostra un errore. C'è un modo per incorporare questo in un ciclo foreach?controllo per variabili nulle

Ad es.

Var Var1 = blah1; 
Var Var2 = blah2; 
Var Var3 = blah3; 
Var Var4 = blah4; 
Var Var5 = blah5; 

foreach(var above, if any is null) 
Errmessage 

Grazie in anticipo

+0

'foreach' richiede che siano in un' IEnumerable'. Se vuoi specificamente 'foreach', dovrai inserire ognuno di questi in una raccolta. –

+0

Stai cercando di controllare ** ALL ** variabili nella funzione locale o solo un sottoinsieme? –

+0

@ p.campbell in realtà per essere precisi foreach ha bisogno di un IEnumerable –

risposta

15

Personalmente, avrei controlli separati per ogni variabile. Su "messaggio di errore" per più controlli di convalida è una cattiva idea.

Il motivo principale per questo è che il "messaggio di errore" dovrebbe probabilmente essere un ArgumentNullException, che dovrebbe fornire il nome del parametro corretto. Questo sarà diverso per variabile. Anche se si utilizza un'eccezione personalizzata, fornire informazioni su quale variabile non è stata specificata correttamente vale lo sforzo di codifica aggiuntivo.

Detto questo, se si vuole fare questo, è possibile utilizzare:

var Var1 = blah1; 
var Var2 = blah2; 
var Var3 = blah3; 
var Var4 = blah4; 
var Var5 = blah5; 

if ((new object[] {Var1, Var2, Var3, Var4, Var5}).Any(v => v==null)) 
    throw new Exception("Your error here"); 
+0

Sono d'accordo, gli assegni separati sono migliori. Se nido tutte le variabili in una istruzione If, ​​c'è un modo per sapere quale variabile è stata nulle? per esempio. if (var1! = null && var2! = null && var3! = null) – user793468

+0

@ user793468 No, non direttamente. Fa parte del problema qui. Se stai solo cercando di abbreviare il codice, potresti usare qualcosa come CuttingEdge.Conditions: http://conditions.codeplex.com/ Ti permetterebbe di scrivere i controlli come una riga per variabile, e comunque di fornire eccezioni relativamente significative. –

3

metterli in una lista di object e ciclo sopra:

List<object> list = new List<object>(); 
list.add(Var1); 
list.add(Var2); 
// etc. 

foreach(object obj in list) 
{ 
    if(obj == null) //message 
} 
4

metterli in tale IEnumerable come un array

foreach(var v in new object[] { var1, var2, .... }){ 
if(v == null) { 
    Errmessage... 
} 
} 
0

Put tutte quelle variabili in una lista. È quindi possibile eseguire il loop su di loro come si desidera.

1

Il mio primo istinto sarebbe di non utilizzare variabili separate ma invece un dizionario:

var dict = new Dictionary<string, object>(); 

dict["var1"] = blah1; 
// etc. 

foreach(var value in dict.Values) 
{ 
    if(value == null) 
     throw new Exception(errorMessage); 
} 
1

Un modo sarebbe quello di tenere traccia di loro in un elenco di lato e poi scorrere la lista:

List<object> objects = new ....; 

Var Var1 = blah1; objects.add(Var1)... 
Var Var2 = blah2; ... 
Var Var3 = blah3; ... 
Var Var4 = blah4; ... 
Var Var5 = blah5; ... 

foreach(var objRef, in objects) 
    if(objRef == null) 
     Errmessage; break ? 
1

Se il numero delle variabili potrebbe cambiare in futuro e non si vuole elencare manualmente tutti loro poi suggerisco usare questo:

using System.Reflection; 

class MyClass{ 
    var Var1; 
    var Var2; 
    ... 
    var infos = typeof(MyClass).GetFields(); 
    foreach(var info in infos) 
    { 
     if(info.GetValue(this)==null) ShowErrorMessage(info.Name); 
    } 
} 

nota: è possibile sostituire con GetFields GetMembers o GetProperties ...

0

al fine di ottenere il "se qualsiasi" semantica si sono dopo, si potrebbe creare una statica classe come segue (l'ho messo nel mio TypeExtensions namespace)

public static class NotAssigned { 
    public static bool AnyOf(params object[] Objects){ 
     foreach (var o in Objects) 
      if (o == null) 
       return true; 
     return false; 
    } 
} 

Uso sarebbe come segue

Var Var1 = blah1; 
Var Var2 = blah2; 
if (NotAssigned.AnyOf(blah1, blah2)) 
    throw new Exception 

Con alcuni aggiustamenti logica minori, si può buttare su una funzione AllOff, forse anche un " "Classe assegnata", con AnyOf e AllOf.

Finora ho utilizzato solo NotAssigned.Anyof

0

È possibile utilizzare l'operatore params parametro da passare un elenco di parametri nulli:

public static void ThrowIfNull(params object[] input) 
    { 
     foreach (var item in input) 
     { 
      //Your choice of how you want to handle this. I chose an exception. 
      throw new NullReferenceException(); 
     } 
    } 

, che vi permetterà di:

int? nullableInt = null; 
    string someNullString = null; 

    ThrowIfNull(nullableInt, someNullString); 

Ci sono anche altri modi per affrontare questo problema . Per esempio è possibile creare un metodo di estensione per IEnumerable:

public static class NullExtensionMethods 
{ 
    public static void ThrowIfHasNull<T>(this IEnumerable collection) 
     where T : Exception, new() 
    { 
     foreach (var item in collection) 
     { 
      if (item == null) 
      { 
       throw new T(); 
      } 
     } 
    } 

    public static void ThrowIfHasNull(this IEnumerable collection) 
    { 
     ThrowIfHasNull<NullReferenceException>(collection); 
    } 
} 

Rendere possibile tutto ciò:

string someNullString = null; 
new string[] { someNullString }.ThrowIfHasNull(); 

//or for context specific exceptions 

new string[] { someNullString }.ThrowIfHasNull<ArgumentNullException>(); 

Anche se io preferisco evitare eccezioni, ove possibile. È possibile apportare le seguenti modifiche:

public static class NullExtensionMethods 
{ 
    public static bool HasNull(this IEnumerable collection) 
    { 
     foreach (var item in collection) 
     { 
      if (item == null) 
      { 
       return true; 
      } 
     } 

     return false; 
    } 
} 

Consentendo di gestire le cose molto più garbo:

var nullDetected = new string[] { someNullString }.HasNull(); 

Dal momento che stiamo usando metodi di estensione, siamo in grado di sfruttare ulteriormente la funzionalità con l'aggiunta di sovraccarichi per casi specifici. Ad esempio, una stringa vuota può essere trattata allo stesso modo String.IsNullOrEmpty. In questo caso vorrei aggiungere un metodo di estensione in più HasNullOrEmpty:

public static bool HasNullOrEmpty(this IEnumerable<string> collection) 
    { 
     foreach (var item in collection) 
     { 
      if (string.IsNullOrEmpty(item)) 
      { 
       return true; 
      } 
     } 

     return false; 
    } 

Anche se il commercio è che il tipo deve essere IEnumerable<string>

0

Questo è il mio modo, contenitore considerato e oggetto Unbox.

Anche se rif può rendere più prestazioni, ma la codifica di passare params è brutto

Uso:

void Bala(Guid? id, int? type){ 
    if (NullableChecker.AnyIsNull(id, type)){ 
     //Do your stuff 
    } 
} 

La classe può utilizzare T4 o strumenti simili per generare il codice

internal static class NullableChecker 
{ 
    public static bool AnyIsNull<T>(T? value) where T : struct 
    { 
     return false == value.HasValue; 
    } 

    public static bool AnyIsNull<T1, T2>(T1? value1, T2? value2) where T1 : struct where T2 : struct 
    { 
     return false == value1.HasValue || false == value2.HasValue; 
    } 

    public static bool AnyIsNull<T1, T2, T3>(T1? value1, T2? value2, T3? value3) where T1 : struct where T2 : struct where T3 : struct 
    { 
     return false == value1.HasValue || false == value2.HasValue || false == value3.HasValue; 
    } 

    public static bool AnyIsNull<T1, T2, T3, T4>(T1? value1, T2? value2, T3? value3, T4? value4) where T1 : struct where T2 : struct where T3 : struct where T4 : struct 
    { 
     return false == value1.HasValue || false == value2.HasValue || false == value3.HasValue || false == value4.HasValue; 
    } 
} 
Problemi correlati