在链式LINQ扩展方法调用中相当于“let”关键字的代码

使用C#编译器的查询理解function,您可以编写如下代码:

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; 

在上面的查询expression式中, let关键字允许将值传递给where和orderby操作,而不重复调用animalName.Length

LINQ扩展方法调用的等效集是什么,实现了“let”关键字在这里的作用?

让我们没有自己的操作; 它捎带Select 。 你可以看到这个,如果你使用“reflection”拆分现有的DLL。

它会是这样的:

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

这里有一篇很好的文章

基本上let创build一个匿名元组。 这相当于:

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

在System.Interactive中还有一个.Let扩展方法,但是它的目的是引入一个lambdaexpression式,在一个stream畅的expression式中被'in-line'评估。 例如,考虑(在LinqPad中说)下面的expression式,每次执行时都会创build新的随机数字:

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

要看到每次都出现新的随机样本,请考虑以下内容

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

这产生左右不同的配对。 为了生成左右alignment总是相同的对,请执行以下操作:

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

如果我们可以直接调用lambdaexpression式,我们可以写

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

但是我们不能像lambdaexpression式那样调用lambdaexpression式。