In questo caso particolare, esso si traduce a:
list.Select(x => SomeComplexExpressionDependingOnx);
Ma ci può essere un caso più complesso, come ad esempio:
from x in list
let v = SomeComplexExpressionDependingOnx
where v > 10 && v+5 < 50 && SomeFunc(v) == "str"
select x
si tradurrà in:
list.Where(x =>
{
var v = SomeComplexExpressionDependingOnx;
return v > 10 && v+5 < 50 && SomeFunc(v) == "str";
}
)
In altre parole, la parola chiave let
è un modo per ridurre e/o ottimizzare la query. Cioè, senza la parola chiave let
che avrebbe dovuto scrivere:
from x in list
where
SomeComplexExpressionDependingOnx > 10 &&
SomeComplexExpressionDependingOnx+5 < 50 &&
SomFunc(SomeComplexExpressionDependingOnx) == "str"
select x
Con conseguente possibile la valutazione tripla della stessa espressione.
Aggiornamento, in seguito a una domanda nel commento.
Primo, cosa c'è di così spaventoso riguardo alle "espressioni di blocco"? Sono solo una scorciatoia per delegati arbitrari. Cioè, la seguente espressione:
Func<string,int> f =
s =>
{
var ln = s.Length;
return ln/2;
}
è equivalente a quanto segue:
int CompilerGeneratedMethodIdentifier0(string s)
{
var ln = s.Length;
return ln/2;
}
...
Func<string, int> f = new Func<string, int>(CompilerGeneratedMethodIdentifier0);
In secondo luogo, cosa c'è di così speciale su "espressioni di blocco"? Lo sapevi che mmm ...chiamiamoli "non-block" le espressioni si espandono anche nello stesso codice? Cioè, il codice semplice new Func<string,int>(s => s.Length/2)
equivale assoluta:
int CompilerGeneratedMethodIdentifier0(string s)
{
return s.Length/2;
}
...
new Func<string, int>(CompilerGeneratedMethodIdentifier0);
Terzo, cosa c'è di così non linqy su "espressioni di blocco"? LINQ utilizza i delegati ovunque e non importa a LINQ quale scorciatoia esatta usi per rappresentare quei delegati.
In particolare, la tua espressione from a in list where a.SomeProp > 10 select new { A = a, B = a.GetB() }
si traduce in quanto segue:
class AnonymousType0
{
public MyClass A { get; set; }
public othertype B { get; set; }
}
bool WhereFunc0(MyClass a)
{
return a.SomeProp > 10;
}
AnonymousType0 SelectResultFunc0(MyClass a)
{
AnonymousType0 result = new AnonymousType0();
result.A = a;
result.B = a.GetB();
return result;
}
...
list
.Where(new Func<MyClass,bool>(WhereFunc0))
.Select(new Func<MyClass,AnonymousType0>(SelectResultFunc0));
Quarto, per ottenere la comprensione di questo tipo, si può solo giocare con la lingua e pensare. Usa il cervello, cioè.
E quinto, se il consiglio precedente non funziona per te per un motivo o per un altro, hai sempre ILSpy. Strumento molto utile, tutti dovrebbero averne uno.
+1 come non avevo usato prima. Informativo. – Kelsey