2013-08-05 11 views
52

Kann ich eine Variable in LINQ deklarieren/verwenden?Kann ich eine Variable in LINQ deklarieren/verwenden? Oder kann ich folgenden LINQ-Clearer schreiben?

Zum Beispiel kann ich folgende LINQ-Clearer schreiben?

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

Gibt es Möglichkeiten, t.ComponentType.GetProperty(t.Name) nicht zweimal hier zu schreiben/zu rufen?

Antwort

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

danke, wusste nicht, lassen. – Cynede

+37

Das Verwenden eines T-Kapitals für eine lokale Variable ist ziemlich verwirrend, da normalerweise erwartet wird, dass T ein generischer Typparameter ist. – Joren

+0

@Joren danke, ich verstehe diese Regel und gilt IMMER in meinem Code. Ich wollte nur einen Großbuchstaben verwenden, um es zu unterscheiden, und ich dachte ohne klaren Grund an den Buchstaben T. Ein anderer Grund ist, dass ich es so schnell wie möglich eintippen wollte, viele andere können es verstehen. Vielleicht in einer SQL-ähnlichen Abfrage, ich sehe Großbuchstaben verwenden ist nicht wirklich schlecht, vor allem ** Variablennamen von nur 1 Brief **, macht es sogar den Code klarer. Fühlst du dich nicht so? –

85

Sie benötigen let:

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

Wenn Sie es in Abfragesyntax tun wollte, können Sie es in einer effizienteren tun könnte (afaik) und sauberer Weg:

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

Ja, mit dem Schlüsselwort let:

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

Es gibt eine Alternative, dass nur wenige Menschen wissen über (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; 

Dies schlägt sich in:

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

Während die let -basierte Version übersetzt:

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

Ein unnötige Zuordnung pro Artikel, weil t immer noch im Bereich ist (noch nicht verwendet). Der C# -Compiler sollte das nur optimieren, aber das tut es nicht (oder die Sprachenspezifikation erlaubt es nicht, nicht sicher).

+0

Heh, dachte, dass "Let" ineffizient war. Ich habe die Antwort mit Ihrer Optimierung als Option zur Verfügung gestellt. Ich wusste nicht, dass es in der Abfragesyntax getan werden könnte. +1. –

Verwandte Themen