2011-12-07 25 views
8

De C# en profundidad:conversión de expresión lambda en un árbol de expresión

No todas las expresiones lambda se pueden convertir a los árboles de expresión. Usted no puede convertir un lambda con un bloque de instrucciones (incluso una sola declaración de retorno ) en un árbol de expresiones -> tiene que estar en el formato que solo evalúa una sola expresión.

Dado que las declaraciones-LINQ a objetos no consigue convertir en objetos de árbol de expresión, las expresiones lambda utilizados con los operadores de LINQ a objetos pueden contener un bloque de instrucciones

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

SALIDA:

one two three four five six 

todavía no he comenzado a aprender LINQ to SQL o LINQ a Entidades, pero supongo que las expresiones lambda utilizados con las declaraciones de LINQ que operan en IQueryable<T> tan sólo puede contener una sola expresión , debido a la restricción de que solo una sola expresión se puede convertir en un árbol de expresiones?

Gracias

Respuesta

14

No se trata sólo de que sólo pueden contener una sola expresión - no puede ser una declaración lambda en absoluto. Incluso un bloque como este:

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

no sería válido para LINQ to SQL. Tendría que ser expresado como:.

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

(he acabo de dar cuenta de que esa es la parte del libro que usted ha citado Ah bien - se nota que soy coherente :)

Nota que a partir de .NET 4, árboles de expresión en sí mismos do tienen la capacidad de contener bloques, pero el compilador de C# no puede traducir la declaración lambdas en ese tipo de árbol de expresiones. También existen otras restricciones, pero rara vez causan problemas.

Esto se especifica en la sección 4.6 de la especificación C# 4:

No todas las funciones anónimas pueden ser representados como árboles de expresión. Por ejemplo, las funciones anónimas con cuerpos de enunciados y funciones anónimas que contienen expresiones de asignación no se pueden representar. En estos casos, todavía existe una conversión, pero fallará en tiempo de compilación.

+5

Ahora, ¿qué demonios sabrías * sobre algo mencionado en ** C# en profundidad **? Oh no importa. –

+0

muchas gracias a ambos – AspOnMyNet

+0

@Jon: de repente me di cuenta de cuán relacionada está esta pregunta con la de http://stackoverflow.com/questions/8405423/do-at-compile-time-linq-to-objects- statements-also-get-translated-into-expressio * wink wink * – AspOnMyNet

1

Tiene razón, solo pueden contener una sola expresión.

Cuestiones relacionadas