Find () и Where (). FirstOrDefault () - PullRequest
131 голосов
/ 18 февраля 2012

Я часто вижу людей, использующих Where.FirstOrDefault() для поиска и захвата первого элемента.Почему бы просто не использовать Find()?Есть ли преимущество перед другим?Я не мог сказать разницу.

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();
        }
    }
}

Ответы [ 5 ]

179 голосов
/ 18 февраля 2012

Где метод Find на IEnumerable<T>? (Риторический вопрос.)

Методы Where и FirstOrDefault применимы к нескольким видам последовательностей, включая List<T>, T[], Collection<T> и т. Д. Любая последовательность, которая реализует IEnumerable<T>, может использовать эти методы. Find доступно только для List<T>. Методы, которые, как правило, более применимы, в таком случае являются более многократно используемыми и оказывают большее влияние.

Полагаю, мой следующий вопрос: зачем они вообще добавили находку? Это хороший совет. Единственное, о чем я могу думать, - это то, что FirstOrDefault может вернуть другое значение по умолчанию, отличное от нуля. Иначе это только кажется бессмысленным дополнением

Find на List<T> предшествует другим методам. List<T> был добавлен с обобщениями в .NET 2.0, а Find был частью API для этого класса. Where и FirstOrDefault были добавлены как методы расширения для IEnumerable<T> с Linq, более поздней версией .NET. Я не могу с уверенностью сказать, что если бы Linq существовал с выпуском 2.0, то Find никогда бы не был добавлен, но это, возможно, относится ко многим другим функциям, которые были в более ранних версиях .NET, которые были сделаны устаревшими или избыточными в более поздних версиях.

42 голосов
/ 02 ноября 2012

Я только что узнал сегодня, выполняя некоторые тесты со списком объектов размером 80K, и обнаружил, что Find() может быть на 1000% быстрее, чем при использовании Where с FirstOrDefault(). Я не знал этого до тестирования таймера до и после каждого из них. Иногда это было в то же время, в противном случае это было быстрее.

27 голосов
/ 18 апреля 2017

Существует очень важное отличие, если источником данных является Entity Framework: Find найдет сущности в состоянии «добавлено», которые еще не сохранены, но Where не найдет.Это по замыслу.

27 голосов
/ 18 февраля 2012

Find только реализовано в List<T>, в то время как Where().FirstOrDefault() работает со всеми IEnumerable<T>.

0 голосов
/ 06 декабря 2018

в дополнение к ответу Энтони Where() просмотреть все записи и затем вернуть результаты, в то время как Find() не нужно проходить через все записи, если предикат совпадает с данным предикатом.

скажем, у вас есть класс List of Test, имеющий свойства id и name.

 List<Test> tests = new List<Test>();
 tests.Add(new Test() { Id = 1, Name = "name1" });
 tests.Add(new Test() { Id = 2, Name = "name2" });
 tests.Add(new Test() { Id = 3, Name = "name3" });
 tests.Add(new Test() { Id = 4, Name = "name2" }); 
 var r = tests.Find(p => p.Name == "name2");
 Console.WriteLine(r.Id);

выдаст результат 2, и только 2 посещений. Найти нужно для получения результата, но если вы используете Where().FirstOrDefault(), мы будем просматривать все записи, а затем получим результаты.

Итак, когда вы знаете, что хотите получить только первый результат из записей в коллекции, Find() будет более подходящим, чем Where().FirtorDefault();

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...