Przykład
Przygotowałem prostą listę, na której będziemy testować te wyrażenia:
var numbers = new List<int> { 12, 42, 1, 10, 12 };
Sprawdzimy 2 różne scenariusze dla każdego wyrażenia. Interesują nas takie przypadki:1) Pobieranie wartości z listy, gdy kilka liczb spełnia warunek.
2) Pobieranie wartości z listy, gdy szukana liczba nie istnieje w tej liście.
First()
var firstValueWhen2Match = numbers.First(x => x == 12);
Console.WriteLine(firstValueWhen2Match);//12
var firstValueWhenDoesntExists = numbers.First(x => x == 0); //System.InvalidOperationException
Console.WriteLine(firstValueWhenDoesntExists);
1) Jeżeli jest więcej wartości spełniających warunek, to gdy użyjesz First(), to zostanie zwrócona tylko pierwsza z nich i to kończy dalsze przeszukiwanie listy.2) Jeżeli First() nie znajdzie żadnej wartości, która spełnia warunek, to zostanie rzucony wyjątek System.InvalidOperationExeption.
FirstOrDefault()
var firstOrDefaultValueWhen2Match = numbers.FirstOrDefault(x => x == 12);
Console.WriteLine(firstOrDefaultValueWhen2Match);//12
var firstOrDefaultValueWhenDoesntExists = numbers.FirstOrDefault(x => x == 0);
Console.WriteLine(firstOrDefaultValueWhenDoesntExists);//0
1) Jeżeli jest więcej wartości spełniających warunek, to gdy użyjesz FirstOrDefault(), to zostanie zwrócona tylko pierwsza z nich i to kończy dalsze przeszukiwanie.2) Jeżeli FirstOrDefault() nie znajdzie żadnej wartości, która spełnia warunek, to zostanie zwrócona domyślna wartość, w tym przypadku 0.
Single()
var singleValueWhen2Match = numbers.Single(x => x == 12);//System.InvalidOperationException
Console.WriteLine(singleValueWhen2Match);
var singleValueWhenDoesntExists = numbers.Single(x => x == 0);//System.InvalidOperationException
Console.WriteLine(singleValueWhenDoesntExists);
1) Jeżeli jest więcej wartości spełniających warunek, to przy użyciu Single() zostanie rzucony wyjątek System.InvalidOperationExeption.2) Jeżeli Single() nie znajdzie żadnej wartości, która spełnia warunek, to zostanie rzucony wyjątek System.InvalidOperationExeption.
SingleOrDefault()
var singleOrDefaultValueWhen2Match = numbers.SingleOrDefault(x => x == 12);//System.InvalidOperationException
Console.WriteLine(singleOrDefaultValueWhen2Match);
var singleOrDefaultValueWhenDoesntExists = numbers.SingleOrDefault(x => x == 0);
Console.WriteLine(singleOrDefaultValueWhenDoesntExists);//0
1) Jeżeli jest więcej wartości spełniających warunek, to przy użyciu SingleOrDefault() zostanie rzucony wyjątek System.InvalidOperationExeption.2) Jeżeli SingleOrDefault () nie znajdzie żadnej wartości, która spełnia warunek, to zostanie zwrócona domyślna wartość, w tym przypadku 0.
W jakich sytuacjach stosować jakie wyrażenia?
1) Jeżeli wiesz, że powinien być tylko jeden rekord (single) spełniający dany warunek i nie może być więcej niż jeden, to wtedy powinieneś użyć Single() lub SingleOrDefault() - w zależności od tego, czy oczekujesz wyjątku, czy wartości domyślnej, gdy nie będzie rekordu spełniającego warunek.
2) Jeżeli interesuje Cię tylko pierwszy rekord (first) spełniający warunek i nie ma dla Ciebie znaczenie, że może być więcej rekordów spełniających ten warunek, to powinieneś użyć First() lub FirstOrDefault() - w zależności od tego, czy oczekujesz wyjątku, czy wartości domyślnej, gdy nie będzie rekordu spełniającego warunek.
3) Pamiętaj też o tym, że wyrażenie First() i FirstOrDefault() jest szybsze niż Single() i SingleOrDefault(), ponieważ już po znalezieniu pierwszej szukanej wartości, dalsze przeszukiwanie kolekcji jest zakończone.
PODSUMOWANIE
W tym krótkim, ale bardzo ważnym artykule przedstawiłem Ci podstawowe różnice pomiędzy 4 popularnymi wyrażeniami z LINQ. Pamiętaj, że nie do każdej sytuacji nadają się wszystkie z nich. Staraj się wybierać odpowiednie wyrażenia w zależności od sytuacji. Również pamiętaj o tym, że rekruterzy często pytają na rozmowach kwalifikacyjnych o podstawowe różnice pomiędzy tymi wyrażeniami, dlatego mam nadzieję, że nie dasz się już zaskoczyć takim pytaniem 🙂
Poprzedni artykuł - Różnica Pomiędzy ViewData, ViewBag oraz TempData.
Następny artykuł - Ref vs Out Na Przykładach w C#