Jak rozumiem, w Linq metoda FirstOrDefault()
może zwrócić Default
wartość czegoś innego niż null. Nie udało mi się ustalić, jakie rzeczy inne niż null mogą być zwracane przez tę (i podobną) metodę, gdy w wyniku zapytania nie ma żadnych elementów. Czy istnieje jakiś szczególny sposób, w jaki można to skonfigurować, aby w przypadku braku wartości dla określonego zapytania zwracana była wstępnie zdefiniowana wartość jako wartość domyślna?
142
YourCollection.FirstOrDefault()
możesz użyćYourCollection.DefaultIfEmpty(YourDefault).First()
na przykład.MyCollection.Last().GetValueOrDefault(0)
do tego. W przeciwnym razie odpowiedź @Jon Skeet poniżej jest poprawna IMO.Odpowiedzi:
Przypadek ogólny, nie tylko dla typów wartości:
Ponownie, to naprawdę nie może powiedzieć, czy coś było w twojej sekwencji, ani czy pierwsza wartość była domyślna.
Jeśli ci na tym zależy, możesz zrobić coś takiego
i użyj jako
chociaż, jak wskazuje Mr. Steak, równie dobrze można by to zrobić
.DefaultIfEmpty(...).First()
.źródło
<T>
w ich nazwach, ale poważniejsze jest to, żevalue == default(T)
nie działa (bo kto wie, czyT
można porównać do równości?)EqualityComparer<T>.Default.Equals(value, default(T))
aby uniknąć boksowania i uniknąć wyjątku, jeśli wartość wynosinull
Nie. Lub raczej zawsze zwraca wartość domyślną dla typu elementu ..., która jest albo odwołaniem o wartości null, wartością zerową typu wartości dopuszczającej wartość null, albo naturalną wartością „wszystkie zera” dla typu wartości nieprzekraczającego wartości null.
W przypadku typów referencyjnych możesz po prostu użyć:
Oczywiście będzie to również daje „drugą wartość domyślną”, jeśli pierwsza wartość jest obecny, ale jest odniesienie zerowa ...
źródło
int
. Wolę użyciaDefaultIfEmpty
:src.Where(filter).DefaultIfEmpty(defaultValue).First()
. Działa zarówno dla typu wartości, jak i typu referencyjnego.Możesz użyć DefaultIfEmpty, a następnie First :
źródło
DefaultIfEmpty
- to działa ze wszystkimi API, które potrzebują domyślny zostać określone:First()
,Last()
, itd. Jako użytkownik nie musi pamiętać API, które pozwalają określić domyślne, które nie. Bardzo elegancko!Z dokumentacji FirstOrDefault
Z dokumentacji domyślnej (T) :
W związku z tym wartością domyślną może być null lub 0 w zależności od tego, czy typ jest odwołaniem, czy typem wartości, ale nie można kontrolować zachowania domyślnego.
źródło
Skopiowano z komentarza @sloth
Zamiast tego
YourCollection.FirstOrDefault()
możesz użyćYourCollection.DefaultIfEmpty(YourDefault).First()
na przykład.Przykład:
źródło
DefaultIfEmpty
zwraca wartość domyślną JEŻELI kolekcja jest pusta (zawiera 0 elementów). Jeśli użyjeszFirst
Z pasującym wyrażeniem, jak w twoim przykładzie, a ten warunek nie znajdzie żadnego elementu, zwrócona wartość będzie pusta.Ty też możesz to zrobić
To używa tylko linq - yipee!
źródło
FirstOrDefault
zamiastFirst
. Według msdn.microsoft.com/en-us/library/bb340482.aspx , zalecane użycie toFirst
Właściwie używam dwóch podejść, aby uniknąć
NullReferenceException
podczas pracy z kolekcjami:Dla języka C # 6.0 lub nowszego:
Użyj
?.
lub,?[
aby sprawdzić, czy jest null przed wykonaniem dostępu do elementu członkowskiego dokumentacji operatorów warunkowychPrzykład:
var barCSharp6 = list.FirstOrDefault()?.Bar;
C # starsza wersja:
Służy
DefaultIfEmpty()
do pobierania wartości domyślnej, jeśli sekwencja jest pusta.Dokumentacja MSDNPrzykład:
string barCSharp5 = list.DefaultIfEmpty(new Foo()).FirstOrDefault().Bar;
źródło
Zamiast tego
YourCollection.FirstOrDefault()
możesz użyćYourCollection.DefaultIfEmpty(YourDefault).First()
na przykład.źródło
Właśnie miałem podobną sytuację i szukałem rozwiązania, które pozwoli mi zwrócić alternatywną wartość domyślną bez zajmowania się nią po stronie dzwoniącego za każdym razem, gdy jej potrzebuję. To, co zwykle robimy, jeśli Linq nie obsługuje tego, czego chcemy, to napisanie nowego rozszerzenia, które się tym zajmie. To jest to co zrobiłem. Oto co wymyśliłem (choć nie przetestowałem):
źródło
Wiem, że minęło trochę czasu, ale dodam do tego, w oparciu o najpopularniejszą odpowiedź, ale z małym rozszerzeniem, chciałbym udostępnić poniżej:
To pozwala mi nazwać to w tekście jako takim na moim własnym przykładzie, z którym miałem problemy:
Tak więc chciałem, aby domyślny program rozpoznawania nazw był używany w tekście, mogę wykonać zwykłe sprawdzenie, a następnie przekazać funkcję, aby klasa nie była tworzona, nawet jeśli nie jest używana, jest to funkcja do wykonania w razie potrzeby!
źródło
Użyj
DefaultIfEmpty()
zamiastFirstOrDefault()
.źródło