C# 等效于链式 LINQ 扩展方法调用中的“let”关键字的代码

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1092687/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 08:02:13  来源:igfitidea点击:

Code equivalent to the 'let' keyword in chained LINQ extension method calls

c#linqextension-methodslinq-to-objects

提问by LBushkin

Using the C# compilers query comprehension features, you can write code like:

使用 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; 

In the query expression above, the letkeyword allows a value to be passed forward to the where and orderby operations without duplicate calls to animalName.Length.

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

What is the equivalent set of LINQ extension method calls that achieves what the "let" keyword does here?

实现“let”关键字在这里所做的事情的等效 LINQ 扩展方法调用集是什么?

采纳答案by Marc Gravell

Let doesn't have its own operation; it piggy-backs off of Select. You can see this if you use "reflector" to pull apart an existing dll.

让没有自己的操作;它搭载于Select. 如果您使用“反射器”来分离现有的 dll,您可以看到这一点。

it will be somethinglike:

这将是什么样:

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

回答by Keltex

There's a good article here

有一个很好的文章在这里

Essentially letcreates an anonymous tuple. It's equivalent to:

本质上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);

回答by Reb.Cabin

There is also a .Let extension method in System.Interactive, but its purpose is to introduce a lambda expression to be evaluated 'in-line' in a fluent expression. For instance, consider (in LinqPad, say) the following expression that creates new random numbers every time it's executed:

System.Interactive 中还有一个 .Let 扩展方法,但其目的是引入一个 lambda 表达式,以在流畅的表达式中“内联”计算。例如,考虑(在 LinqPad 中)以下表达式,每次执行时都会创建新的随机数:

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

To see that new random samples show up every time, consider the following

要查看每次都出现新的随机样本,请考虑以下事项

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

which produces pairs in which the left and right are different. To produce pairs in which the left and right are always the same, do something like the following:

产生左右不同的对。要生成左右始终相同的对,请执行以下操作:

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

If we could invoke lambda expressions directly, we might write

如果我们可以直接调用 lambda 表达式,我们可能会写

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

But we can't invoke lambda expressions as if they were methods.

但是我们不能像调用方法一样调用 lambda 表达式。

回答by Fabio Angela

about Code equivalent to the 'let' keyword in chained LINQ extension method calls

关于与链式 LINQ 扩展方法调用中的“let”关键字等效的代码

above comment is no more valid

以上评论不再有效

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();

produces

产生

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)

so multiple letare optimized now

所以let现在优化了多个