Código equivalente à palavra-chave ‘let’ em chamadas de método de extensão LINQ encadeadas

Usando os resources de compreensão de consulta de compiladores C #, você pode escrever código como:

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; 

Na expressão de consulta acima, a palavra-chave let permite que um valor seja passado adiante para as operações where e orderby sem chamadas duplicadas para animalName.Length .

Qual é o conjunto equivalente de chamadas de método de extensão LINQ que atinge o que a palavra-chave “let” faz aqui?

Let não tem sua própria operação; é piggy-backs de Select . Você pode ver isso se você usar “refletor” para separar uma dll existente.

será algo como:

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

Tem um bom artigo aqui

Essencialmente, let criar uma tupla anônima. É equivalente a:

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

Há também um método de extensão .Let no System.Interactive, mas sua finalidade é introduzir uma expressão lambda para ser avaliada ‘in-line’ em uma expressão fluente. Por exemplo, considere (no LinqPad, digamos) a seguinte expressão que cria novos números randoms toda vez que é executada:

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

Para ver que novas amostras aleatórias aparecem todas as vezes, considere as seguintes

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

que produz pares nos quais a esquerda e a direita são diferentes. Para produzir pares nos quais a esquerda e a direita são sempre as mesmas, faça algo como o seguinte:

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

Se pudéssemos invocar expressões lambda diretamente, poderíamos escrever

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

Mas não podemos invocar expressões lambda como se fossem methods.