2011-12-07 34 views
8

da C# in profondità:Conversione espressione lambda in un albero di espressione

Non tutte le espressioni lambda possono essere convertiti in alberi di espressione. È impossibile convertire un lambda con un blocco di istruzioni (anche solo una dichiarazione di ritorno ) in un albero di espressione -> deve essere nel formato che valuta solo una singola espressione.

Dal dichiarazioni LINQ to Object non ottengono convertiti in oggetti albero di espressione, le espressioni lambda utilizzati con gli operatori LINQ to Object possono contenere un blocco di istruzioni

 string[] count = { "one ", "two ", "three ", "four ", "five ", "six " }; 
     IEnumerable<int> result = count.Select(item => 
           { 
            Console.WriteLine(item); 
            return item.Length; 
           }); 
     foreach (int i in result); 

USCITA:

one two three four five six 

non ho ancora iniziato a studiare LINQ to SQL o LINQ to Entities, ma suppongo espressioni lambda utilizzati con le dichiarazioni LINQ che operano su IQueryable<T> può sempre e solo contenere una singola espressione , a causa del restristion che solo una singola espressione può essere convertita in un albero di espressione?

si

risposta

14

Grazie Non è solo che essi possono contenere solo una singola espressione - non può essere una lambda dichiarazione a tutti. Anche un blocco di questo tipo:

var result = query.Select(item => { return item.Length; }); 

non valido per LINQ to SQL. Avrebbe dovuto essere espresso come:.

var result = query.Select(item => item.Length); 

(ho appena notato che questo è il bit del libro che hai citato Oh bene - si vede che sono coerenti :)

Nota che a partire dal .NET 4, alberi di espressione stessi do hanno la capacità di contenere blocchi, ma il compilatore C# non può tradurre enunciati lambdas in quel tipo di albero di espressioni. Ci sono anche altre restrizioni, ma raramente causano problemi.

Questo è riportato alla sezione 4.6 del C# 4 spec:

Non tutte le funzioni anonime possono essere rappresentati come alberi di espressione. Ad esempio, le funzioni anonime con corpi di istruzioni e funzioni anonime contenenti espressioni di assegnazione non possono essere rappresentate. In questi casi, una conversione esiste ancora, ma fallirà in fase di compilazione.

+5

Ora, che diavolo * dovresti sapere di qualcosa menzionato in ** C# in Profondità **? Oh non importa. –

+0

grazie mille – AspOnMyNet

+0

@Jon: improvvisamente mi sono reso conto di quanto sia correlata questa domanda a http://stackoverflow.com/questions/8405423/do-at-compile-time-linq-to-objects- dichiarazioni-anche-ottenere-tradotto-in-expressio * wink wink * – AspOnMyNet

1

Sei corretto, possono contenere solo una singola espressione.