使用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”关键字在这里的作用?
答案 0 :(得分:237)
让我们没有自己的行动;它背负着Select
。如果使用“reflector”来拉开现有的dll,就可以看到这一点。
它将是 之类的东西:
var result = names
.Select(animalName => new { nameLength = animalName.Length, animalName})
.Where(x=>x.nameLength > 3)
.OrderBy(x=>x.nameLength)
.Select(x=>x.animalName);
答案 1 :(得分:85)
有一篇好文章here
基本上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);
答案 2 :(得分:6)
System.Interactive中还有一个.Let扩展方法,但其目的是引入一个lambda表达式,以便在一个流畅的表达式中“在线”进行求值。例如,考虑(在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();
如果我们可以直接调用lambda表达式,我们可以编写
(xs => xs.Zip(xs, Tuple.Create))(seq.Take(3).ToList()).Dump();
但是我们不能像调用方法那样调用lambda表达式。
答案 3 :(得分:0)
关于Code equivalent to the 'let' keyword in chained LINQ extension method calls
以上评论不再有效
var x = new List<int> { 2, 3, 4, 5, 6 }.AsQueryable();
(from val in x
let val1 = val
let val2 = val + 1
where val2 > val1
select val
).Dump();
产生
System.Collections.Generic.List`1[System.Int32]
.Select(
val =>
new
{
val = val,
val1 = val
}
)
.Select(
temp0 =>
new
{
temp0 = temp0,
val2 = (temp0.val + 1)
}
)
.Where(temp1 => (temp1.val2 > temp1.temp0.val1))
.Select(temp1 => temp1.temp0.val)
现在优化了多个let