2013-03-12 24 views
5

是否有可能創建一個擴展方法來返回對象列表中的單個屬性或字段?如何收集對象列表中的單個屬性?

目前我有很多功能如下。

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

這是「硬編碼」,只在單個對象類型中提供單個屬性。它的乏味,我敢肯定,有一種使用LINQ/Reflection來創建擴展方法,可以以通用和可重用的方式做到這一點。這樣的事情:

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

除了最簡單的方法使用LINQ,我也尋找最快的方法。是否有可能使用代碼生成(和Lambda表達式樹)在運行時創建此類方法?我相信這會比使用Reflection更快。

+0

你的功能可以寫成「motions.Select(motion => motion.Speed)」。這不完全是通用的,但一開始它比每次寫入和調用方法要短得多。 – nvoigt 2013-03-12 13:58:12

+0

只調用我的方法可能會更快。 (LINQ通常比非泛型代碼慢) – 2013-03-12 13:58:56

回答

7

你可以這樣做:

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

,並用它喜歡:

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

這是值得懷疑這種方法是否比只有更好直接使用SelectToList

5

它,沒有反射需要:

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

如何創建擴展方法來執行此操作?我不想每次都寫這段代碼。我如何使用代碼生成來創建最快的方法? – 2013-03-12 13:57:43

+0

public static List GetValues (this List target,Func selector){return target.Select(selectoror);} – 2013-03-12 14:22:32

+1

但是不需要創建函數,Select * is *已經是一個函數 – 2013-03-12 14:23:12

1

for循環將是我認爲最快的,緊隨其後的是linq(如果您不使用閉包,則開銷最小)。我無法想象任何其他機制會比這更好。

您可以將List<int>替換爲int[]或用特定容量初始化列表。這可能會加快你的代碼比其他任何事情都多(儘管還不算多)。

相關問題