2013-03-12 10 views
5

Czy można utworzyć metodę rozszerzenia, aby zwrócić pojedynczą właściwość lub pole na liście obiektów?Jak zebrać jedną właściwość na liście obiektów?

Obecnie mam wiele funkcji, takich jak następujące.

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

To jest "zakodowane na sztywno" i obsługuje tylko jedną właściwość w typie pojedynczego obiektu. Jest żmudny i jestem pewien, że istnieje sposób użycia LINQ/Reflection do stworzenia metody rozszerzenia, która może to zrobić w sposób ogólny i wielokrotnego użytku. Coś takiego:

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

Oprócz najprostszej metody przy użyciu LINQ, szukam również najszybszej metody. Czy jest możliwe użycie generowania kodu (i drzewek wyrażeń Lambda) do stworzenia takiej metody w czasie wykonywania? Jestem pewien, że byłoby to szybsze niż użycie Reflection.

+0

Funkcję można zapisać jako "ruchy. Wybierz (ruch => ruch.speed)". Nie jest to generyczne, ale na początek jest o wiele krótsze niż pisanie i wywoływanie metody za każdym razem. – nvoigt

+0

Tylko wywoływanie mojej metody może być szybsze. (LINQ jest zwykle wolniejszy niż kod niepoliczalny) –

Odpowiedz

7

Można zrobić:

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

i używać go lubię:

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

to wątpliwe, czy ta metoda jest lepsza niż tylko bezpośrednio za pomocą Select i ToList.

5

To jest, bez refleksji potrzebne:

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

Jak utworzyć metodę rozszerzenia, aby to zrobić? Nie chcę za każdym razem pisać tego fragmentu. I jak używać generowania kodu do stworzenia najszybszej metody? –

+0

publiczna lista statyczna GetValues ​​ (ta lista: target, Func selektor) {return target.Wybierz (selectoror);} –

+1

, ale nie trzeba tworzyć funkcji, wybierz * jest * funkcja już –

1

Pętla for była najszybsza, myślę, a następnie linq (minimalny narzut, jeśli nie używasz zamknięć). Nie mogę sobie wyobrazić żadnego innego mechanizmu, który byłby lepszy od tego.

Można wymienić List<int> na int[] lub zainicjować listę z określoną pojemnością. Prawdopodobnie zrobiłoby to więcej, aby przyspieszyć twój kod niż cokolwiek innego (choć wciąż niewiele).

Powiązane problemy