如何对对象列表的特定字段求和 [英] how to sum particular field of list of Objects
问题描述
嗨朋友们,
我需要对对象列表的特定字段求和。我编写了一个接受列表但不知道如何传递字段名称的方法。
例如,如果我传递 MarketValue
它应该返回MarketValue总和如果我通过数量
它应该返回数量总和
这是我的班级
Hi Friends,
I need to sum particular field of list of Objects. I have written a method with accepts Lists but don't know how to pass the field name.
For Example if i pass MarketValue
it should return MarketValue Sum like wise if i pass Quantity
it should return Quantity Sum
This is my class
public class TopList
{
public static double marketsum = 1;
public string Symbol{get;set;}
public double MarketValue{get;set;}
public double PreviousMarketVale{get;set;}
public double Quantity{get;set;}
public double MarketValuePercentage { get { return Math.Round((MarkrtValue / marketsum) * 100,2); } }
public double ChangeInMarketValue {get { return Math.Round(((MarkrtValue-PreviousMarketVale)/MarkrtValue)*100,2);}}
}
我的方法
My Method
public static double MarketSum(List<TopList>tl)//here it should accept one more paramter
{
return tl.Sum(s => s.MarketValue);//here i need to pass different fields
}
这就是我调用方法的方法
This is how i invoke the method
List<TopList> tl = new List<TopList>();
double ms = MarketSum(tl);
提前致谢:)
Thanks in advance :)
推荐答案
I只是抽象方法之外的字段选择:
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 },
// etc.
};
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.
我可能会声明另一个类来包含你的列表并在该类中包含sum方法。
I would probably declare another class to contain your list and include the sum methods on that class.
public class TopListItem
{
public static double marketsum = 1;
public string Symbol { get; set; }
public double MarketValue { get; set; }
public double PreviousMarketVale { get; set; }
public double Quantity { get; set; }
public double MarketValuePercentage { get { return Math.Round((MarketValue / marketsum) * 100, 2); } }
public double ChangeInMarketValue { get { return Math.Round(((MarketValue - PreviousMarketVale) / MarketValue) * 100, 2); } }
}
public class TopList
{
public static List<toplistitem> items { get; set; }
static TopList()
{
items = new List<toplistitem>();
}
public double sumQuantity()
{
//Sum them here
return 0;
}
}
要调用:
To invoke:
TopList t1 = new TopList();
double totalQuantity = t1.sumQuantity();
这篇关于如何对对象列表的特定字段求和的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!