Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to collect a single property in a list of objects?

Is it possible to create an extension method to return a single property or field in a list of objects?

Currently I have a lot of functions like the following.

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

This is "hard coded" and only serves a single property in a single object type. Its tedious and I'm sure there's a way using LINQ / Reflection to create an extension method that can do this in a generic and reusable way. Something like this:

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

Apart from the easiest method using LINQ, I'm also looking for the fastest method. Is it possible to use code generation (and Lambda expression trees) to create such a method at runtime? I'm sure that would be faster than using Reflection.

like image 796
Robin Rodricks Avatar asked Mar 12 '13 13:03

Robin Rodricks


1 Answers

You could do:

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

and use it like:

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

it's questionable whether this method is better than just using Select and ToList directly though.

like image 93
Lee Avatar answered Nov 14 '22 21:11

Lee