C# 如何在对象列表中收集单个属性?

C# 如何在对象列表中收集单个属性?,c#,.net,oop,reflection,code-generation,C#,.net,Oop,Reflection,Code Generation,是否可以创建一个扩展方法来返回对象列表中的单个属性或字段 目前我有很多类似下面的功能 public static List<int> GetSpeeds(this List<ObjectMotion> motions) { List<int> speeds = new List<int>(); foreach (ObjectMotion motion in motions) { speeds.Add(motion.S

是否可以创建一个扩展方法来返回对象列表中的单个属性或字段

目前我有很多类似下面的功能

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;
}
公共静态列表GetSpeeds(此列表){
列表速度=新列表();
foreach(运动中的对象运动){
速度。添加(运动。速度);
}
返回速度;
}
这是“硬编码”的,仅为单个对象类型中的单个属性提供服务。这很乏味,我相信有一种方法可以使用LINQ/反射来创建一个扩展方法,该方法可以以通用和可重用的方式来实现这一点。大概是这样的:

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;
}
公共静态列表GetProperties(此列表对象、属性属性属性){
列表道具=新列表();
foreach(对象中的ObjectMotion对象){
添加道具(对象道具??);
}
返回道具;
}

除了使用LINQ最简单的方法外,我还寻找最快的方法。是否可以使用代码生成(和Lambda表达式树)在运行时创建这样的方法?我相信这会比使用反射更快。

是的,不需要反射:

List<int> values = motions.Select(m=>m.Speed).ToList();
List values=motions.Select(m=>m.Speed.ToList();
您可以执行以下操作:

public static List<TProp> GetProperties<T, TProp>(this IEnumerable<T> seq, Func<T, TProp> selector)
{
    return seq.Select(selector).ToList();
}
public static List GetProperties(此IEnumerable seq,Func选择器)
{
返回seq.Select(selector.ToList();
}
然后像这样使用它:

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

但是,这种方法是否比直接使用
Select
ToList
更好还值得怀疑。

for循环是我认为最快的,紧随其后的是linq(如果不使用闭包,则开销最小)。我想象不出还有比这更好的机制


您可以使用
int[]
替换
列表
,或者使用特定容量初始化列表。这可能比任何其他方法都更能提高代码的速度(尽管仍然不多)。

我如何创建一个扩展方法来实现这一点?我不想每次都写这个片段。如何使用代码生成来创建最快的方法?公共静态列表GetValues(此列表目标,Func选择器){return target.Select(selector);}但无需生成函数,Select是一个函数,您可以将函数编写为“motions.Select(motion=>motion.Speed)”。这并不完全是通用的,但首先,它比每次编写和调用一个方法要短得多。只调用我的方法可能会更快。(LINQ通常比非泛型代码慢)