Accepted answer

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)


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


  val =>
         val = val,
         val1 = val
  temp0 =>
         temp0 = temp0,
         val2 = (temp0.val + 1)
.where(temp1 => (temp1.val2 > temp1.temp0.val1))
.select(temp1 => temp1.temp0.val)

so multiple let are optimized now


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 =>;

to see that new random samples show up every time, consider the following, 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 =>, tuple.create)).dump(); 

if we could invoke lambda expressions directly, we might write

(xs =>, tuple.create))(seq.take(3).tolist()).dump();

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


there's a good article here

essentially let creates an anonymous tuple. it's equivalent to:

var result =
  animal => new { animal = animal, namelength = animal.length })
.where(x => x.namelength > 3)
.orderby(y => y.namelength)
.select(z => z.animal);

Related Query

More Query from same tag