Find () vs.Where ().FirstOrDefault()

Często widzę ludzi używających Where.FirstOrDefault() do wyszukiwania i chwytania pierwszego elementu. Dlaczego po prostu nie użyć Find()? Czy jest jakaś przewaga dla drugiego? Nie mogł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();
        }
    }
}
Author: Wai Ha Lee, 2012-02-18

4 answers

Gdzie jest metoda Find Na IEnumerable<T>? (Pytanie retoryczne.)

Metody Where i FirstOrDefault mają zastosowanie do wielu rodzajów sekwencji, w tym List<T>, T[], Collection<T>, itd. Każda sekwencja implementująca IEnumerable<T> może używać tych metod. Find jest dostępny tylko dla List<T>. Metody, które są ogólnie bardziej odpowiednie, są wtedy bardziej wielokrotnego użytku i mają większy wpływ.

Moje następne pytanie brzmi, dlaczego w ogóle dodali znalezisko. To jest dobra rada. Jedyne co mi przychodzi do głowy to to, że pierwsza wartość może zwrócić inną wartość domyślną niż null. W przeciwnym razie wydaje się to po prostu bezsensownym dodatkiem

Find on List<T> wyprzedza inne metody. {[4] } został dodany z generics w. NET 2.0, A Find był częścią API dla tej klasy. Where i FirstOrDefault zostały dodane jako rozszerzenia dla IEnumerable<T> z Linq, który jest późniejszą wersją. NET. Nie mogę z całą pewnością powiedzieć, że gdyby Linq istniał z wydaniem 2.0 to Find nigdy by nie zostało dodane, ale prawdopodobnie tak jest w przypadku wielu innych funkcji, które pojawiły się we wcześniejszych wersjach.NET, które zostały przestarzałe lub zbędne przez późniejsze wersje.

 152
Author: Anthony Pegram,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-17 20:52:52

Właśnie się dzisiaj dowiedziałem, robiąc kilka testów na liście 80K obiektów i okazało się, że Find() może być do 1000% szybszy niż użycie Where z FirstOrDefault(). Nie wiedziałem o tym, dopóki nie przetestowałem zegara przed i po każdym wszystkim. Czasami było to w tym samym czasie, inaczej było szybciej.

 38
Author: digiben,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-02 01:22:29

Find jest tylko zaimplementowane w List<T>, podczas gdy Where().FirstOrDefault() działa ze wszystkimi IEnumerable<T>.

 25
Author: penartur,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-17 20:39:24

Istnieje bardzo ważna różnica, jeśli źródłem danych jest Encja Framework: Find znajdzie encje w stanie "dodany", które nie są jeszcze utrzymane, ale Where nie będzie. To z założenia.

 20
Author: Chalky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-18 00:20:02