2013-03-12 2 views
5

Ist es möglich, eine Erweiterungsmethode zu erstellen, um eine einzelne Eigenschaft oder ein einzelnes Feld in einer Objektliste zurückzugeben?Wie wird eine einzelne Eigenschaft in einer Liste von Objekten gesammelt?

Derzeit habe ich viele Funktionen wie folgt.

public static List<int> GetSpeeds(this List<ObjectMotion> motions) { 
    List<int> speeds = new List<int>(); 
    foreach (ObjectMotion motion in motions) { 
     speeds.Add(motion.Speed); 
    } 
    return speeds; 
} 

Dies ist "hart codiert" und dient nur einer einzigen Eigenschaft in einem einzigen Objekttyp. Es ist mühsam und ich bin mir sicher, dass es eine Möglichkeit gibt, LINQ/Reflection zu verwenden, um eine Erweiterungsmethode zu erstellen, die dies generisch und wiederverwendbar macht. Etwas wie folgt aus:

public static List<TProp> GetProperties<T, TProp>(this List<T> objects, Property prop){ 
    List<TProp> props = new List<TProp>(); 
    foreach (ObjectMotion obj in objects) { 
     props.Add(obj.prop??); 
    } 
    return props; 
} 

Neben der einfachste Methode, mit LINQ, ich bin auch für die schnellste Methode suchen. Ist es möglich, Code-Generierung (und Lambda-Ausdruck-Bäume) zu verwenden, um eine solche Methode zur Laufzeit zu erstellen? Ich bin mir sicher, dass das schneller wäre als Reflection.

+0

Ihre Funktion könnte geschrieben werden als "motions.Select (motion => motion.Speed)". Das ist nicht ganz allgemein, aber für den Anfang ist es viel kürzer als jedes Mal eine Methode zu schreiben und aufzurufen. – nvoigt

+0

Nur der Aufruf meiner Methode ist möglicherweise schneller. (LINQ ist normalerweise langsamer als nicht-generischer Code) –

Antwort

7

Sie tun können:

public static List<TProp> GetProperties<T, TProp>(this IEnumerable<T> seq, Func<T, TProp> selector) 
{ 
    return seq.Select(selector).ToList(); 
} 

und verwenden Sie es mögen:

List<int> speeds = motions.GetProperties(m => m.Speed); 

es ist fraglich, ob diese Methode besser ist als nur mit Select und ToList direkt aber.

5

Es ist keine Reflexion erforderlich:

List<int> values = motions.Select(m=>m.Speed).ToList(); 
+0

Wie erstelle ich eine Erweiterungsmethode? Ich möchte dieses Snippet nicht jedes Mal schreiben. Und wie verwende ich die Code-Generierung, um die schnellste Methode zu erstellen? –

+0

öffentliche statische Liste GetValues ​​ (diese Liste Ziel, Func Selektor) {zurück target.Select (selectoror);} –

+1

aber keine Notwendigkeit, eine Funktion zu machen, Select * ist * eine Funktion bereits –

1

Eine for-Schleife wäre die schnellste, denke ich, dicht gefolgt von linq (minimaler Aufwand, wenn Sie keine Verschlüsse verwenden). Ich kann mir keinen anderen Mechanismus vorstellen, der besser wäre.

Sie könnten die List<int> durch eine int[] ersetzen oder die Liste mit einer bestimmten Kapazität initialisieren. Das würde wahrscheinlich mehr tun, um Ihren Code zu beschleunigen als alles andere (obwohl immer noch nicht viel).

Verwandte Themen