在链式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式。