LINQ эквивалент List <T>.Find()?

Я просматриваю код, который принимает 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 >

Ответ 1

Среднее значение LINQ должно было бы использовать FirstOrDefault:

var match = myEnumerable.FirstOrDefault(value => value.Aaa == aaa && value.Bbb == bbb);

Ответ 2

Для справки, вот таблица некоторых старых методов экземпляра класса 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) всегда проходит через всю последовательность (начиная с первого элемента) и только затем возвращает наиболее "недавнее" соответствие.

Ответ 3

Или вы можете сделать следующее:

var match = myEnumerable.Where(value => value.Aaa == aaa && value.Bbb == bbb)
                        .FirstOrDefault();