2011-12-19 7 views
5

Mam wiele zmiennych, które ustawiłem przed utworzeniem obiektu, chcę sprawdzić, czy któraś z tych zmiennych w null, jeśli dowolna zmienna, następnie wyświetla błąd. Czy istnieje sposób włączenia tego w pętlę foreach?sprawdź zmienne zerowe

Na przykład.

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

foreach(var above, if any is null) 
Errmessage 

góry dzięki

+0

'foreach' wymaga, aby były w' IEnumerable'. Jeśli konkretnie chcesz 'foreach', musisz umieścić każdą z nich w kolekcji. –

+0

Czy chcesz sprawdzić ** ALL ** zmiennych w funkcji lokalnej lub tylko podzbiór? –

+0

@ p.campbell faktycznie być precyzyjnie foreach potrzebuje IEnumerable –

Odpowiedz

15

Osobiście osobiście sprawdzałbym każdą zmienną. "Komunikat o błędzie" dla wielu sprawdzeń sprawdzających jest złym pomysłem.

Głównym powodem tego jest to, że "komunikat o błędzie" powinien być prawdopodobnie ArgumentNullException, który powinien zawierać poprawną nazwę parametru. To będzie się różnić w zależności od zmiennej. Nawet jeśli używasz niestandardowego wyjątku, dostarczenie informacji o , która została nieprawidłowo określona zmienną, jest warte dodatkowego wysiłku związanego z kodowaniem.

W takiej sytuacji, jeśli chcesz to zrobić, można użyć:

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

Zgadzam się, oddzielne kontrole są lepsze. Jeśli zagnieżdżę wszystkie zmienne w jednej instrukcji If, czy istnieje sposób na sprawdzenie, która zmienna ma wartość zerową? na przykład if (var1! = null && var2! = null && var3! = null) – user793468

+0

@ user793468 Nie, nie bezpośrednio. To część problemu tutaj. Jeśli próbujesz skrócić kod, możesz użyć czegoś takiego jak CuttingEdge.Conditions: http://conditions.codeplex.com/ Pozwoliłby ci napisać czeki jako jedną linię na zmienną i nadal zapewnia względnie znaczące wyjątki. –

3

umieścić je w wykazie object i pętli nad nim:

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

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

Umieść je w IEnumerable takich jak tablica

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

Sprzedaży wszystkie te zmienne do listy. Możesz następnie pętli nad nimi, jak chcesz.

1

Moim pierwszym skojarzeniem byłoby nie używać oddzielnych zmiennych lecz jeden słownik:

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

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

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

Jednym ze sposobów byłoby śledzić je na liście z boku, a następnie pętli listy:

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

Jeżeli liczba zmiennych może się zmienić w przyszłości i nie chcesz, aby ręcznie wymienić wszystkich z nich potem proponuję użyć tego:

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); 
    } 
} 

uwaga: można zastąpić GetFields z GetMembers lub GetProperties ...

0

aby uzyskać „czy jakieś” semantyka jesteś po, można utworzyć statyczną klasa następująco (I umieścić go w moim nazw TypeExtensions)

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

Wykorzystanie byłby następujący

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

z kilku drobnych korekt logicznych, można rzucić na funkcję AllOff, także być może " Przypisana "klasa, z AnyOf i AllOf.

Do tej pory korzystałem tylko z NotAssigned.AnyOf

0

Można użyć operatora params parametr przekazać listę parametrów zerowych:

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(); 
     } 
    } 

który pozwoli Ci:

int? nullableInt = null; 
    string someNullString = null; 

    ThrowIfNull(nullableInt, someNullString); 

Istnieją także inne sposoby podejścia do tego problemu . Na przykład można utworzyć metodę rozszerzenia dla 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); 
    } 
} 

Making to możliwe:

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

//or for context specific exceptions 

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

Choć wolę uniknąć wyjątki, gdzie to możliwe. Można wprowadzić następujące zmiany:

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

     return false; 
    } 
} 

Pozwala na dużo bardziej wdzięcznie obsłużyć rzeczy:

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

Skoro jesteśmy przy użyciu metody rozszerzenie, możemy dodatkowo wykorzystać funkcję dodając przeciążeń dla poszczególnych przypadków. Na przykład pusty ciąg może być traktowany w taki sam sposób, jak String.IsNullOrEmpty. W tym przypadku chciałbym dodać dodatkową metodę rozszerzenia HasNullOrEmpty:

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

     return false; 
    } 

Choć handel jest, że typ musi być IEnumerable<string>

0

To jest mój sposób, uważany pudełko i unbox przedmiot.

Nawet ref może sprawić większą wydajność, ale kodowanie przekazać params jest brzydki

useage:

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

Klasa może używać T4 lub podobnych narzędzi do generowania kodu

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; 
    } 
} 
Powiązane problemy