it-swarm.com.ru

Код, эквивалентный ключевому слову let, в цепочечных вызовах методов расширения LINQ

Используя функции понимания запросов компиляторами C #, вы можете написать код:

var names = new string[] { "Dog", "Cat", "Giraffe", "Monkey", "Tortoise" };
var result =
    from animalName in names
    let nameLength = animalName.Length
    where nameLength > 3
    orderby nameLength
    select animalName; 

В приведенном выше выражении запроса ключевое слово let позволяет передавать значение в операции where и orderby без повторных вызовов animalName.Length.

Каков эквивалентный набор вызовов метода расширения LINQ, который достигает того, что здесь делает ключевое слово "let"?

183
LBushkin

Пусть не имеет своей собственной операции; это спекуляция от Select. Вы можете увидеть это, если вы используете "рефлектор", чтобы отделить существующую DLL.

это будет что-то как:

var result = names
        .Select(animalName => new { nameLength = animalName.Length, animalName})
        .Where(x=>x.nameLength > 3)
        .OrderBy(x=>x.nameLength)
        .Select(x=>x.animalName);
239
Marc Gravell

Там есть хорошая статья здесь

По сути, let создает анонимный кортеж. Это эквивалентно:

var result = names.Select(
  animal => new { animal = animal, nameLength = animal.Length })
.Where(x => x.nameLength > 3)
.OrderBy(y => y.nameLength)
.Select(z => z.animal);
85
Keltex

Существует также метод расширения .Let в System.Interactive, но его цель - ввести лямбда-выражение, которое будет оцениваться "in-line" в беглом выражении. Например, рассмотрим (скажем, в LinqPad) следующее выражение, которое создает новые случайные числа при каждом выполнении:

var seq = EnumerableEx.Generate(
    new Random(),
    _ => true,
    _ => _,
    x => x.Next());

Чтобы увидеть, что новые случайные выборки появляются каждый раз, рассмотрите следующее

seq.Zip(seq, Tuple.Create).Take(3).Dump();

который производит пары, в которых левый и правый различны. Чтобы создать пары, в которых левый и правый всегда одинаковы, сделайте что-то вроде следующего:

seq.Take(3).ToList().Let(xs => xs.Zip(xs, Tuple.Create)).Dump(); 

Если бы мы могли вызывать лямбда-выражения напрямую, мы могли бы написать

(xs => xs.Zip(xs, Tuple.Create))(seq.Take(3).ToList()).Dump();

Но мы не можем вызывать лямбда-выражения, как если бы они были методами.

6
Reb.Cabin