By LBushkin


2009-07-07 14:31:56 8 Comments

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

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 let keyword allows a value to be passed forward to the where and orderby operations without duplicate calls to animalName.Length.

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

4 comments

@Fabio Angela 2019-06-21 14:25:50

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

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 let are optimized now

@Keltex 2009-07-07 14:39:12

There's a good article here

Essentially let creates an anonymous tuple. It's equivalent to:

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

@JB. 2015-07-21 14:03:26

I quote the article above it seems prudent to recommend against using the let keyword in cases where you do not need to transform a variable

@Monsignor 2019-09-12 09:58:57

I quote it further: This could be considered a micro-optimisation

@Reb.Cabin 2011-06-06 18:01:25

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:

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

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

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

@Marc Gravell 2009-07-07 14:46:00

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.

it will be something like:

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

@David Pfeffer 2010-09-22 15:31:51

Woah, I didn't know you could autoencapsulate using the new operator like that.

@Reb.Cabin 2011-04-30 00:10:04

You can also use the little "lambda" button in the result pane of LinqPad to see the generated code if you start with a Queryable. In other words, if you change your first line to var names = new string [] { "Dog", ... }.AsQueryable(); then run the whole thing in LinqPad, click the little lambda button, you will see generated code virtually identical to Marc's answer.

@justanotherdev 2015-12-21 07:08:37

I needed to use the .Dump() extension method in LinqPad to see the resulting lambda.

Related Questions

Sponsored Content

34 Answered Questions

[SOLVED] What is the Java equivalent for LINQ?

  • 2009-08-01 18:53:26
  • Ahmed
  • 263295 View
  • 790 Score
  • 34 Answer
  • Tags:   java linq

21 Answered Questions

[SOLVED] LINQ equivalent of foreach for IEnumerable<T>

20 Answered Questions

[SOLVED] Why there is no ForEach extension method on IEnumerable?

9 Answered Questions

[SOLVED] Learning about LINQ

15 Answered Questions

[SOLVED] Can I add extension methods to an existing static class?

7 Answered Questions

[SOLVED] How do I use reflection to call a generic method?

4 Answered Questions

[SOLVED] C# and LINQ - arbitrary statement instead of let

2 Answered Questions

[SOLVED] A Linq ContainsAll Method?

  • 2014-09-26 12:08:23
  • Steven Wood
  • 1313 View
  • 0 Score
  • 2 Answer
  • Tags:   c# linq

150 Answered Questions

2 Answered Questions

[SOLVED] Nice, clean cross join in Linq using only extension methods

Sponsored Content