2010-08-25 10 views
64

Actuando sobre la respuesta a mi pregunta Select a model property using a lambda and not a string property name, queriendo añadir propiedades a una colección de la siguiente manera:¿Por qué algunas propiedades de objeto son UnaryExpression y otras MemberExpression?

var props = new ExportPropertyInfoCollection<JobCard>(); 
props.Include(model => model.BusinessInstallNumber).Title("Install No").Width(64).KeepZeroPadding(true); 
props.Include(model => model.DeviceName).Title("Device").Width(70); 
props.Include(model => model.DateRequested).Title("Request Date").Format("{0:dd/MM/yyyy}").Width(83); 

que escribió el código siguiente en el Include método:

public class PropertyCollection<T> 
{ 
    public void Include(Expression<Func<T, object>> expression) 
    { 
     var memberExpression = expression.Body as MemberExpression; 
     if (memberExpression != null) 
     { 
      var pes = new ExportPropertyInfoBuilder {Property = new ExportPropertyInfo {Property = memberExpression.Member as PropertyInfo}}; 
      Properties.Add(pes.Property.Property.Name, pes.Property); 
      return pes; 
    } 

Sin embargo, en el funcionamiento de la código, encontré algunas de las lambdas rindieron MemberExpression valores como se esperaba, pero otros dieron UnaryExpression valores. Tenía que cambiar la primera línea de código a la siguiente antes de que pudiera añadir todos mis inmueble con lambdas:

var memberExpression = expression.Body as MemberExpression ?? ((UnaryExpression) expression.Body).Operand as MemberExpression; 

Todas las propiedades son tipos 'simples', es decir, la secuencia, DateTime, int, bool, etc. un objeto comercial de POCO. Están decorados con varios atributos DataAnnotaciones.

Lo que hace que algunas de las lambdas en mi ejemplo para producir MemberExpression valores y otros UnaryExpression valores? En mi ejemplo, el primer UnaryExpression está en la tercera línea, la propiedad DateTime, pero las propiedades booleanas también dan como resultado UnaryExpressions.

+0

significa la expresión UnaryExpression puede que se producen en la presencia (o 'unpresence') de columnas anulables * *? – leppie

+0

@leppie, sospecho que está en columnas que no admiten nulos. En mi ejemplo, el primer UnaryExpression está en un DateTime, donde las MemberExpressions anteriores están en cadenas. Una posterior UnaryExpression está en bool. – ProfK

+0

Investigaré un poco. He utilizado (o más bien abusado) expresiones como esta antes, y nunca tuve problemas, lo que significa que siempre fue un 'MemberExpression', de lo contrario, mi código fallaría. ¿En qué versión de .NET se está ejecutando? Yo no uso .NET 4 todavía. – leppie

Respuesta

51

Creo que sé cuál es el problema. Su expresión devuelve el tipo object.

Si cambia esto a Expression<Func<T, R>>, el tipo de devolución debe inferirse correctamente, y UnaryExpression (que supongo que es una operación de boxeo) no debería ocurrir.

Actualización:

La firma para Include debe ser:

public void Include<T, R>(Expression<Func<T, R>> expression) 
+1

Disculpa mi estupidez, pero ¿qué debería ser R? No puedo convertirlo en MemberExpression, porque MemberExression está en la propiedad Body de la expresión. Estoy de acuerdo en que el UnaryExpression es probablemente debido al boxeo sin embargo. – ProfK

+3

@ProfK: R simplemente se deduce, será el tipo de propiedad que se devuelve. Probablemente no lo uses, pero podrías :) – leppie

+1

Creo que veo lo que está sucediendo. Como el tipo de devolución de expresión es un objeto, está encuadrado.Con un tipo de devolución tipeado, esto no sucede. Gracias @leppie! Confíe en un hombre funcional para ayudar aquí :-) – ProfK

Cuestiones relacionadas