2010-08-25 10 views
64

Agendo sulla risposta alla mia Select a model property using a lambda and not a string property name domanda, volendo aggiungere proprietà ad una collezione come segue:Perché alcune proprietà dell'oggetto UnaryExpression e altri 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); 

ho scritto il seguente codice nel metodo Include:

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

Tuttavia, a correre il codice, ho trovato alcuni dei lambda restituiti MemberExpression valori come previsto, ma altri hanno restituito valori UnaryExpression. Ho dovuto cambiare la prima riga di codice al seguente prima che potessi aggiungere tutte le mie proprietà utilizzando lambda:

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

Tutti i beni sono 'semplici' tipi, cioè stringa, DateTime, int, bool, ecc un oggetto aziendale POCO. Sono decorati con diversi attributi DataAnnotations.

Quali sono le cause alcune delle lambda nel mio esempio a cedere MemberExpression valori e altri UnaryExpression valori? Nel mio esempio, il primo UnaryExpression si trova sulla terza riga, la proprietà DateTime, ma le proprietà booleane determinano anche UnariaExpressioni.

+0

significa l'espressione UnaryExpression forse si verificano in presenza (o 'unpresence') di colonne nullable * *? – leppie

+0

@leppie, ho il sospetto che sia su colonne non annullabili. Nel mio esempio, il primo UnaryExpression si trova su un DateTime, dove le precedenti MemberExpressions sono su stringhe. Una successiva espressione unaria è su un bool. – ProfK

+0

Investigherò un po '. Ho usato (o piuttosto abusato) espressioni come questa in precedenza, e non ho mai avuto problemi, il che significa che è sempre stato un 'MemberExpression' altrimenti il ​​mio codice sarebbe fallito. Su quale versione di .NET stai lavorando? Non uso ancora .NET 4. – leppie

risposta

51

Penso di sapere qual è il problema. L'espressione restituisce il tipo object.

Se si cambia questo per Expression<Func<T, R>> il tipo di ritorno deve essere correttamente dedotto, e UnaryExpression (che io presumo sia qualche operazione di pugilato) non dovrebbe verificarsi.

Aggiornamento:

La firma per Include dovrebbe essere:

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

Scusa il mio stupido qui, ma cosa dovrebbe essere R? Non riesco a renderlo MemberExpression, perché MemberExpression si trova nella proprietà Body dell'espressione. Sono d'accordo che l'espressione unaria è probabilmente a causa della boxe però. – ProfK

+3

@ProfK: R viene semplicemente dedotto, sarà il tipo di proprietà restituita. Probabilmente non lo userai, ma potresti :) – leppie

+1

Penso di vedere cosa sta succedendo. Poiché l'espressione restituisce il tipo è oggetto, è in scatola.Con un tipo di reso digitato, questo non accade. Grazie a @leppie! Fidati di un uomo funzionale per aiutare qui :-) – ProfK

Problemi correlati