Często widzę, jak ludzie Where.FirstOrDefault()
wyszukują i chwytają pierwszy element. Dlaczego po prostu nie użyć Find()
? Czy druga strona ma przewagę? Nie potrafiłem odróżnić.
namespace LinqFindVsWhere
{
class Program
{
static void Main(string[] args)
{
List<string> list = new List<string>();
list.AddRange(new string[]
{
"item1",
"item2",
"item3",
"item4"
});
string item2 = list.Find(x => x == "item2");
Console.WriteLine(item2 == null ? "not found" : "found");
string item3 = list.Where(x => x == "item3").FirstOrDefault();
Console.WriteLine(item3 == null ? "not found" : "found");
Console.ReadKey();
}
}
}
c#
linq
linq-to-objects
KingOfHypocrites
źródło
źródło
list.FirstOrDefault(x => x == "item3");
jest bardziej zwięzły niż użycie obu.Where
i.FirstOrDefault
.Find
poprzedza LINQ. (był dostępny w .NET 2.0 i nie można było używać lambd. Zmuszono Cię do używania normalnych metod lub metod anonimowych)Odpowiedzi:
Gdzie jest
Find
metodaIEnumerable<T>
? (Pytanie retoryczne.)Where
IFirstOrDefault
sposoby są stosowane wobec wielu gatunków, w tym sekwencjeList<T>
,T[]
,Collection<T>
itp dowolnej sekwencji narzędziaIEnumerable<T>
może używać tych metod.Find
jest dostępny tylko dlaList<T>
. Sposoby, które są stosowane bardziej powszechnie, to wówczas bardziej wielokrotnego użytku i ma większy wpływ.Find
naList<T>
wyprzedza inne metody.List<T>
został dodany z typami ogólnymi w .NET 2.0 iFind
był częścią interfejsu API dla tej klasy.Where
iFirstOrDefault
zostały dodane jako metody rozszerzające dlaIEnumerable<T>
Linq, który jest późniejszą wersją .NET. Nie mogę powiedzieć z całą pewnością, że gdyby Linq istniał w wydaniu 2.0,Find
który nigdy nie zostałby dodany, ale prawdopodobnie tak jest w przypadku wielu innych funkcji, które pojawiły się we wcześniejszych wersjach .NET, które stały się przestarzałe lub zbędne w późniejszych wersjach.źródło
Where(condition).FirstOrDefault()
optymalizuje przynajmniej równie dobrze, a czasem lepiej niżFirstOrDefault(condition)
samodzielnie. Zawsze staramyWhere()
się uzyskać lepszą wydajność, gdy jest dostępna.Właśnie dowiedziałem się dzisiaj, robiąc kilka testów na liście 80 000 obiektów i stwierdziłem, że
Find()
może to być nawet o 1000% szybsze niż użycieWhere
zFirstOrDefault()
. Nie wiedziałem o tym, dopóki nie przetestowałem timera przed i po każdym. Czasami był to ten sam czas, w przeciwnym razie szybciej.źródło
.ToList()
lub.ToArray()
faktycznie wykonałeś zapytanie.Find
korzysta z kluczy podstawowych (stąd indeksów), podczas gdyWhere
jest to zwykłe zapytanie sqlIstnieje bardzo ważna różnica, jeśli źródłem danych jest Entity Framework:
Find
znajdzie jednostki w stanie „dodanym”, które nie zostały jeszcze utrwalone, aleWhere
tak się nie stanie. Jest to zgodne z projektem.źródło
Find
jest zaimplementowany tylko wList<T>
, podczas gdyWhere().FirstOrDefault()
działa ze wszystkimiIEnumerable<T>
.źródło
oprócz Anthony'ego odpowiedz na
Where()
wizytę we wszystkich rekordach, a następnie zwróć wynik (y) bezFind()
konieczności przechodzenia przez wszystkie rekordy, jeśli predykat pasuje do podanego predykatu.więc powiedz, że masz List of Test klasy posiadającej
id
iname
właściwości.Daje wyjście
2
i tylko 2 wizyty Znajdź potrzebne do podania wyniku, ale jeśli używaszWhere().FirstOrDefault()
, odwiedzimy wszystkie rekordy, a następnie otrzymamy wyniki.Tak więc, gdy wiesz, że chcesz, aby tylko pierwszy wynik z rekordów w kolekcji
Find()
był bardziej odpowiedniWhere().FirtorDefault();
źródło
FirstOrDefault
„rozpali się” łańcuch i przestanie wyliczać wszystko. Używam terminu „bubble-up” z powodu braku lepszego wyrażenia, ponieważ w rzeczywistości każdy selektor / predykat zostanie przekazany do następnego, więc ostatnia metoda w łańcuchu faktycznie wykonuje pracę jako pierwsza.Wow, po prostu oglądam dzisiaj samouczek EF z MicrosofToolbox na Youtube. Powiedział o używaniu Find () i FirstOrDefault (warunek) w zapytaniu, a Find () wyszuka dane, które zrobiłeś na tym obiekcie (dodałeś, edytujesz lub usuniesz - ale nie zostały jeszcze zapisane w bazie danych), tymczasem FirstOrDefault będzie tylko szukaj tego, co już zostało zapisane
źródło
Find()
jest IEnumerable odpowiednikiem aFirstOrDefault()
. Nie powinieneś łączyć obu .Where () z,.FirstOrDefault()
ponieważ.Where()
przechodzi przez całą tablicę, a następnie będzie iterować po tej liście, aby znaleźć pierwszy element. Możesz zaoszczędzić niesamowitą ilość czasu, umieszczając predykat wyszukiwania wFirstOrDefault()
metodzie.Zachęcam również do przeczytania połączonego pytania do tego wątku, aby dowiedzieć się więcej o lepszych wynikach używania
.Find()
w określonych scenariuszach Wydajność Find () vs. FirstOrDefault ()źródło