2013-08-05 12 views

risposta

79
var q = from PropertyDescriptor t in TypeDescriptor.GetProperties(instance) 
     let u = t.ComponentType.GetProperty(t.Name) 
     where (u != null) 
     select u; 
+3

grazie, non sapevo di let. – Cynede

+37

L'utilizzo di una T maiuscola per una variabile locale è piuttosto confuso, poiché normalmente ci si aspetterebbe che T fosse un parametro di tipo generico. – Joren

+0

@Joren grazie, capisco questa regola e la applico SEMPRE nel mio codice. Volevo solo usare una lettera maiuscola per distinguerla e ho pensato alla lettera T senza una ragione chiara, un'altra ragione è che volevo scriverla il più velocemente possibile, molti altri possono capirlo. Forse in una "query simile a SQL", vedo che usare le lettere maiuscole non è poi così male, in particolare i nomi delle ** variabili di solo 1 lettera **, rende persino più chiaro il codice. Non ti senti così? –

85

È necessario let:

var q = from PropertyDescriptor t in TypeDescriptor.GetProperties(instance) 
     let name = t.ComponentType.GetProperty(t.Name) 
     where (name != null) 
     select name; 

Se si voleva fare in sintassi di query, si potrebbe fare in modo più efficiente (afaik) e più pulita:

var q = TypeDescriptor 
      .GetProperties(instance) 
      .Select(t => t.ComponentType.GetProperty(t.Name)) 
      .Where(name => name != null); 
14

Sì, utilizzando la parola chiave let:

var q = from PropertyDescriptor t in TypeDescriptor.GetProperties(instance) 
    let nameProperty = t.ComponentType.GetProperty(t.Name) 
    where (nameProperty != null) 
    select nameProperty; 
7

C'è un'alternativa che poche persone conoscono (select a into b):

var q = from PropertyDescriptor t in TypeDescriptor.GetProperties(instance) 
     select t.ComponentType.GetProperty(t.Name) into u 
     where u != null 
     select u; 

Questo si traduce in:

var q = TypeDescriptor.GetProperties(instance) 
     .Select(t => t.ComponentType.GetProperty(t.Name)) 
     .Where(prop => prop != null); 

considerando che la versione basata su let si traduce in:

var q = TypeDescriptor.GetProperties(instance) 
     .Select(t => new { t, prop = t.ComponentType.GetProperty(t.Name) }) 
     .Where(x => x.prop != null) 
     .Select(x => x.prop); 

An allocazione non necessaria per articolo perché t è ancora in ambito (non ancora utilizzato). Il compilatore C# dovrebbe semplicemente ottimizzarlo, ma non lo fa (o le specifiche del linguaggio non lo consentono, non sono sicuro).

+0

Heh, pensava che "let" fosse inefficiente. Ho fornito la risposta con l'ottimizzazione come opzione. Non sapevo che si potesse fare nella sintassi delle query. +1. –