Я часто вижу людей, использующих 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();
}
}
}
c#
linq
linq-to-objects
KingOfHypocrites
источник
источник
list.FirstOrDefault(x => x == "item3");
является более кратким, чем использование обоих.Where
и.FirstOrDefault
.Find
предшествует LINQ. (он был доступен в .NET 2.0, и вы не могли использовать лямбды. Вы были вынуждены использовать обычные методы или анонимные методы)Ответы:
Где
Find
методIEnumerable<T>
? (Риторический вопрос.)Where
ИFirstOrDefault
методы применимы в отношении нескольких видов последовательностей, в том числеList<T>
,T[]
,Collection<T>
и т.д. Любой последовательности , которая реализуетIEnumerable<T>
могут использовать эти методы.Find
доступно только дляList<T>
. Методы, которые обычно более применимы, затем более пригодны для повторного использования и оказывают большее влияние.Find
наList<T>
предшествующих другие методы.List<T>
был добавлен с обобщениями в .NET 2.0 иFind
был частью API для этого класса.Where
иFirstOrDefault
были добавлены в качестве методов расширения дляIEnumerable<T>
Linq, более поздней версии .NET. Я не могу с уверенностью сказать, что если бы существовал Linq с выпуском 2.0,Find
который никогда не был бы добавлен, но это, возможно, относится ко многим другим функциям, которые были в более ранних версиях .NET, которые были сделаны устаревшими или избыточными в более поздних версиях.источник
Where(condition).FirstOrDefault()
оптимизирует хотя бы так же, а иногда и лучше, чем вFirstOrDefault(condition)
одиночку. Мы всегда используем,Where()
чтобы получить улучшенную производительность, когда она доступна.Я только что узнал сегодня, выполняя некоторые тесты со списком объектов размером 80 КБ, и обнаружил, что это
Find()
может быть до 1000% быстрее, чем с помощьюWhere
withFirstOrDefault()
. Я не знал этого до тестирования таймера до и после каждого из них. Иногда это было в то же время, в противном случае это было быстрее.источник
.ToList()
или,.ToArray()
чтобы фактически выполнить запрос.Find
что использует первичные ключи (следовательно, индексы), в тоWhere
время как простой запрос sqlСуществует очень важное различие, если источником данных является Entity Framework:
Find
найдет объекты в состоянии «добавлено», которые еще не сохранены, ноWhere
не будут. Это по замыслу.источник
Find
реализовано только вList<T>
то время какWhere().FirstOrDefault()
работает со всемиIEnumerable<T>
.источник
в дополнение к ответу Энтони,
Where()
просмотрите все записи и затем верните результат (ы), в то время какFind()
не нужно просматривать все записи, если предикат совпадает с заданным предикатом.скажем, у вас есть список
id
иname
свойства класса Test .Даст результат
2
, и только 2 посещения. Найдите необходимые для получения результата, но если вы используете,Where().FirstOrDefault()
мы будем посещать все записи, а затем мы получим результаты.Таким образом, когда вы знаете, что хотите только первый результат из записей в коллекции,
Find()
будет более подходящим, чемWhere().FirtorDefault();
источник
FirstOrDefault
«раздувает» цепь и перестанет все перечислять. Я использую термин «всплывающее» из-за отсутствия лучшего выражения, потому что фактически каждый селектор / предикат будет передан следующему, поэтому последний метод в цепочке фактически выполняет работу в первую очередь.Ничего себе, я просто смотрю учебник EF от MicrosofToolbox сегодня на Youtube. Он говорил об использовании Find () и FirstOrDefault (условие) в запросе, а Find () будет искать данные, которые вы выполнили для этого объекта (добавить, изменить или удалить - но еще не сохранили в базе данных), в то время как FirstOrDefault будет только искать то, что уже было сохранено
источник
Find()
является IEnumerable эквивалентом aFirstOrDefault()
. Вы не должны связывать оба .Where () с,.FirstOrDefault()
потому что он.Where()
проходит через весь массив, а затем будет перебирать этот список, чтобы найти первый элемент. Вы экономите невероятное количество времени, помещая свой предикат поиска вFirstOrDefault()
метод.Кроме того, я рекомендую вам прочитать связанный вопрос с этой веткой, чтобы узнать больше о лучших показателях использования
.Find()
в конкретных сценариях производительности Find () по сравнению с FirstOrDefault ().источник