So I have a generic list of objects, and I need to combine their properties to get list of sums.
public class PickupReport
{
public int Units { get; set; }
public int Revenue { get; set; }
public int Accs { get; set; }
}
public class ReportBase<TReport>
{
public List<TReport> Reports { get; set; }
public List<int> Sum
{
get
{
return new List<int>{1,2,3}
}
}
}
So, if I have
var reportBase = new ReportBase<PickupReport>();
reportBase.Reports = new List<PickupReport>{
new PickupReport{Units = 1, Revenue = 2, Accs = 3},
new PickupReport{Units = 4, Revenue = 5, Accs = 6},
new PickupReport{Units = 2, Revenue = 3, Accs = 4}
}
I need to get and calculate reportBase.Sum
and it should be List<int>
with {7, 10, 13}
Like {the sum of property #1 for all objects, the sum of property #2 for all objects, and so on.. }
Is it possible to do this somehow, given that the number of objects in the list is dynamic? Well, the number of object properties, too, but within the class.
@MongZhu only int
Then I would suggest to use reflection for this approach. Make it a method rather then a property:
public class ReportBase<TReport>
{
public List<TReport> Reports { get; set; }
public IEnumerable<int> CalculateSum()
{
foreach (var element in typeof(TReport).GetProperties())
{
if (element.PropertyType == typeof(int))
{
yield return Reports.Sum(x => (int)element.GetValue(x));
}
}
}
}
Explanation:
This method iterates over all properties that are in the type and if it finds a property of type int
it will calculate the sum of it from the entire list.
Here is a testprogramm and the result dump from LINQPad:
void Main()
{
var reportBase = new ReportBase<PickupReport>();
reportBase.Reports = new List<PickupReport>{
new PickupReport(1,2,3),
new PickupReport(4,5,6),
new PickupReport(2,3,4)
};
reportBase.CalculateSum().Dump();
}
EDIT:
just noticed, that objects in my project can have two types of properties, not one
Here is a version where you can add types to a list of allowed sum up types:
public class ReportBase<TReport>
{
public List<TReport> Reports { get; set; }
List<Type> possibleTypes = new List<Type> {typeof(int), typeof(double)};
public IEnumerable<double> CalculateSum()
{
foreach (PropertyInfo element in typeof(TReport).GetProperties())
{
if (possibleTypes.Contains(element.PropertyType))
{
yield return Reports.Sum(x => Convert.ToDouble(element.GetValue(x)));
}
}
}
}
Now you can also handle double
This should get you a List<int>
with the sums of all int
properties of TReport
:
var properties = typeof(PickupReport).GetProperties();
List<int> sum = new List<int>();
for (int i = 0; i<properties.Length; ++i)
{
sum.Add(0);
if (properties[i].PropertyType == typeof(int))
{
foreach (var report in reportBase.Reports)
{
sum[i] += (int) properties[i].GetValue(report);
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.