2013-07-04 12 views
7

W funkcji IEnumerable.First, jak mogę obsłużyć przypadku, jeśli nie ma żadnych dopasowań? Obecnie to właśnie wywala ...Jak obsłużyć przypadek dopasowania w List.First wC#?

MySPListItem firstItem = itemCollection.First(item => !item.isFolder); 
if (firstItem != null) 
{ 
    TreeNode firstNode = GetNodeByListItem(my_treeview.Nodes, firstItem, ReportObject); 
    if (firstNode != null) 
    { 
     ReportObject.log("Selecting the first PDF"); 
     selectPDF(my_treeview, firstNode, queryStr_param); 
    } 
} 

Komunikat o błędzie:

sekwencja zawiera żadnego elementu pasującego
StackTrace: w System.Linq.Enumerable.First [TSource] (IEnumerable orzecznika)

+0

Jeśli nie ma dopasowania, zwróci wartość domyślną dla tego typu .. ('null' dla klasy, domyślna dla struktury). Wpisz swój kod, a my będziemy mogli powiedzieć, gdzie wystąpił błąd. –

+0

Wykonuję test zerowy, ale zawiesza się on na linii gdzie używam Find ... – omega

+2

Alternatywnie, dlaczego nie użyć LINQ's FirstOrDefault (item => item.item.ID == PDFID) – Dann

Odpowiedz

14

Ok, jeśli to wyjątkowy aby istniała nie pierwszy

try 
{ 
    var first = enumerable.First(); 
} 
catch (InvalidOperationException) 
{ 
    // Oops, that was exceptional. 
} 

Jeśli przewidujesz, że może nie być pierwsza w niektórych ważnych sytuacjach:

var first = enumerable.FirstOrDefault(); 
if (first == default(someType)) // null for reference types. 
{ 
    // Ok, I need to deal with that. 
} 
+0

To jest lepsza odpowiedź niż zaakceptowana. Zwięzłe i rozważa * dlaczego * wyjątek został zgłoszony. –

+0

Jaka jest różnica między 'default (someType)' a 'null'? – omega

+0

@omega 'default (T)' zwraca domyślną wartość typu. Dla typu referencyjnego jest to zawsze 'null', więc w twoim przypadku są wymienne. Jeśli chcesz, aby kod działał z typami wartości (struct i prymitywy), wówczas 'default (T)' zapewnia ogólne rozwiązanie. Oczywiście, jeśli znasz typ, możesz po prostu użyć literału równego wartości domyślnej, co i tak robi kompilator. – Jodrell

2

cytat z MSDN website ty związane z:

Pierwszy element, który pasuje do warunków zdefiniowanych przez określony predykat, jeśli został znaleziony; w przeciwnym razie wartość domyślna dla typu T.

Opisuje wartość zwracaną. W związku z tym, gdy nie zostanie znaleziony żaden wynik, zwracana jest wartość default dla typu T, co oznacza, że ​​dla typów referencyjnych jest to null i rzeczy takie, jak współrzędne. dla typów wartości.

Tak więc w kodzie wywołującym, po prostu sprawdź tę domyślną wartość i wszystko jest w porządku :-). To, czego nie możesz zrobić, to po prostu użyć zwracanej wartości, np. może spowodować NullReferenceException, jeśli używasz typu odniesienia.

0

Sprawdź, czy wynik jest null:

if (result == null) 
    { 
     Console.WriteLine("Not found"); 
    } 

Istnieje wyraźny przykład wykazanie, co zrobić, jeśli przedmiot znajduje się/nie znaleziono here

+1

@Dvvvoter - ............ –

0

Nie należy wyrzucać wyjątek, trzeba do obsługi przypadku, w którym zwraca wartość domyślną (T). Może pojawić się wyjątek NullReferenceException, ponieważ nie obsługujesz przypadku, w którym zwraca wartość null. Na przykład:

IEnumerable<Cars> cars = GetCars(); 
Car car = cars.Find(c => c.Model == "Astra"); 
if(car != null) 
{ 
    // You found a car! 
} 

Jeśli robią to samo dla struct, chcesz sprawdzić, to zamiast domyślnego. Ints na przykład byłoby 0:

int[] ints = new int[] { 1, 4, 7 }; 
int myInt = ints.Find(i => i > 5); 
if(myInt != 0) // 0 is default(int) 
{ 
    // You found a number 
} 
7

Podczas zrobić null czek na znalezisku, nie robić w orzecznika. Linia

foundItem = itemCollection.Find(item => item.item.ID == PDFID); 

Może wyjątek to item jest null (masz wstawiony element null w kolekcji?) Lub item.item jest null (jesteś pewien, że to zawsze tam?).

Można zrobić:

foundItem = itemCollection.Find(item => item != null && 
             item.item != null && 
             item.item.ID == PDFID); 

Bardziej rozmowni, ale nie dostanie NullReferenceException.

Edytuj Cóż, zmieniłeś pytanie. Teraz robisz First.Metoda będzie generować wyjątek, jeśli nic nie zostanie znalezione. Zamiast tego użyj FirstOrDefault, która zwróci null dla klasy lub wartości domyślnej dla struct.

foundItem = itemCollection.FirstOrDefault(item => item != null && 
               item.item != null && 
               item.item.ID == PDFID); 
+0

Dodałem komunikat o wyjątku. Nie sądzę, że tak jest, ponieważ przedmiot jest zerowy. – omega

+0

Zobacz moją aktualizację. Zmieniłaś metodę (była to "Znajdź", ale teraz jest "Najpierw"). –

+1

Tak, dziękuję, "FirstOrDefault" jest to potrzebne. – omega

3

Wymień najpierw FirstOrDefault:

MySPListItem firstItem = itemCollection.FirstOrDefault(item => !item.isFolder); 
+0

Czy ten przemyślnik może się rozwinąć? – Larry