I'd just abstract the field selection outside of the method:
public static double MarketSum(List<TopList>tl, Func<TopList, double> accessor)
{
return tl.Sum(accessor);
}
Calling it as:
List<TopList> tl = new List<TopList>();
double ms = MarketSum(tl, s => s.MarketValue);
Another option is to pre-define the accessor functions:
private static Dictionary<string, Func<TopList, double>> Accessors = new Dictionary<string, Func<TopList, double>>() {
{ "MarketValue", s => s.MarketValue },
{ "Quantity", s => s.Quantity },
};
public static double MarketSum(List<TopList>tl, string accessorKey)
{
Func<TopList, double>> accessor;
if (!Accessors.TryGetValue(accessorKey, out accessor))
throw new InvalidOperationException("No such accessor: " + accessorKey);
return tl.Sum(accessor);
}
Calling it as:
List<TopList> tl = new List<TopList>();
double ms = MarketSum(tl, "MarketValue");
A third option is to use reflection to automatically pre-define the accessor functions:
public static Dictionary<string, Func<TopList, double>> Accessors = GetPropertyAccessDictionary<TopList, double>();
static Dictionary<string, Func<Tclass, Tvalue>> GetPropertyAccessDictionary<Tclass, Tvalue>()
{
Dictionary<string, Func<Tclass, Tvalue>> accessors = new Dictionary<string, Func<Tclass, Tvalue>>();
PropertyInfo[] props = typeof(Tclass).GetProperties(BindingFlags.Public);
Type valueType = typeof(Tvalue);
foreach (var prop in props)
{
MethodInfo getter = prop.GetMethod;
if (valueType.IsAssignableFrom(getter.ReturnType))
accessors.Add(prop.Name, o => (Tvalue)(getter.Invoke(o, null)));
}
return accessors;
}
public static double MarketSum(List<TopList> tl, string accessorKey)
{
Func<TopList, double> accessor = null;
if (!Accessors.TryGetValue(accessorKey, out accessor))
throw new InvalidOperationException("No such accessor: " + accessorKey);
return tl.Sum(accessor);
}
Use it exactly the same as above.
The string-based lookup of the accessors is not a great architecture. It's OK if the strings are coming directly from user input. Even then, it's probably better to parse and validate that into something more structured.