Ответ 1
Среднее значение LINQ должно было бы использовать FirstOrDefault:
var match = myEnumerable.FirstOrDefault(value => value.Aaa == aaa && value.Bbb == bbb);
Я просматриваю код, который принимает IEnumerable<T>
и преобразует его в List<T>
, поэтому он может использовать List<T>.Find(predicate)
:
var myEnumerable = ...;
var myList = new List<T>(myEnumerable);
var match = myList.Find(value => value.Aaa == aaa && value.Bbb == bbb);
Есть ли способ переписать это с помощью методов расширения LINQ, которые имеют такой же эффект, но без создания дополнительного List<T>
в качестве промежуточного шага?
FirstOrDefault(source, predicate)
метод расширения выглядит как хороший кандидат, но пытается выяснить, соответствует ли он точно эквиваленту Find
. p >
Среднее значение LINQ должно было бы использовать FirstOrDefault:
var match = myEnumerable.FirstOrDefault(value => value.Aaa == aaa && value.Bbb == bbb);
Для справки, вот таблица некоторых старых методов экземпляра класса List<>
.NET 2 и их эквивалентных методов расширения в Linq:
METHOD IN List<> METHOD IN Linq
------------------------------------------------------------------------------------------
list.Contains(item) query.Contains(item)
list.Exists(x => x.IsInteresting()) query.Any(x => x.IsInteresting())
list.TrueForAll(x => x.IsInteresting()) query.All(x => x.IsInteresting())
list.Find(x => x.IsInteresting()) query.FirstOrDefault(x => x.IsInteresting())
list.FindLast(x => x.IsInteresting()) query.LastOrDefault(x => x.IsInteresting())
list.FindAll(x => x.IsInteresting()) query.Where(x => x.IsInteresting())
list.ConvertAll(x => x.ProjectToSomething()) query.Select(x => x.ProjectToSomething())
Конечно, некоторые из них не совсем эквивалентны. В частности, Linq Where
и Select
используют отложенное выполнение, а FindAll
и ConvertAll
of List<>
будут выполняться немедленно и возвращать ссылку на новый экземпляр List<>
.
FindLast
часто будет быстрее, чем LastOrDefault
, потому что FindLast
фактически ищет, начиная с конца List<>
. С другой стороны, LastOrDefault(predicate)
всегда проходит через всю последовательность (начиная с первого элемента) и только затем возвращает наиболее "недавнее" соответствие.
Или вы можете сделать следующее:
var match = myEnumerable.Where(value => value.Aaa == aaa && value.Bbb == bbb)
.FirstOrDefault();