我有一个由以下类定义的对象的列表:
internal class Aggregate
{
public string fieldName { get; set; }
public double Count { get; set; }
public double Min { get; set; }
public double Max { get; set; }
}
其中fieldName
可以是Value
,LowLimit
或HighLimit
我想要转换成定义为的对象列表:
public class KpiValue
{
public double Value { get; set; }
public double? LowLimit { get; set; }
public double? HighLimit { get; set; }
public AggregateType AggregateType { get; set; }
}
public enum AggregateType
{
Count,
Min,
Max
}
我很天真地研究了它(用MCVE编辑):
var input = new List<Aggregate> {
new Aggregate() {fieldName = "Value",Count = 5,Min = 2,Max = 3 },
new Aggregate() {fieldName = "HighLimit",Count = 6,Min = 5,Max = 8 },
new Aggregate() {fieldName = "LowLimit",Count = 2,Min = 9,Max = 15 } };
List<KpiValue> values = new List<KpiValue>();
values.Add(new KpiValue()
{
AggregateType = AggregateType.Count,
Value = input.SingleOrDefault(l => l.fieldName == "Value").Count,
HighLimit = input.SingleOrDefault(l => l.fieldName == "HighLimit").Count,
LowLimit = input.SingleOrDefault(l => l.fieldName == "LowLimit").Count
});
values.Add(new KpiValue()
{
AggregateType = AggregateType.Min,
Value = input.SingleOrDefault(l => l.fieldName == "Value").Min,
HighLimit = input.SingleOrDefault(l => l.fieldName == "HighLimit").Min,
LowLimit = input.SingleOrDefault(l => l.fieldName == "LowLimit").Min
});
values.Add(new KpiValue()
{
AggregateType = AggregateType.Count,
Value = input.SingleOrDefault(l => l.fieldName == "Value").Max,
HighLimit = input.SingleOrDefault(l => l.fieldName == "HighLimit").Max,
LowLimit = input.SingleOrDefault(l => l.fieldName == "LowLimit").Max
});
我一直在寻找一种改进的方法,并且似乎可以通过使用反射as in this question将代码放入循环中来实现。
但是,在阅读有关实现方法的内容时,我也了解到了这种反思is not very efficient, and that it is mostly used with external libraries
在这种情况下,Reflection是可行的方式,还是我应该保留重复的代码? (或者还有更好的第三种方法吗?)
编辑:
在这个例子中,性能并不是至关重要的,因为数据库调用非常长,由于反射引起的任何开销都不会引起注意。我只是在尝试the right thing™
答案 0 :(得分:1)
您实际上不必重复代码,只需要将逻辑包装在一个方法中
public KpiValue BuildKpiValue(AggregationType aggregation,
IEnumerable<Aggregate> list,
Func<Aggregate, double> readValue)
{
return new KpiValue()
{
AggregateType = aggregation,
Value = readValue(list.Single(l => l.fieldName == "Value")),
HighLimit = readValue(list.Single(l => l.fieldName == "HighLimit")),
LowLimit = readValue(list.Single(l => l.fieldName == "LowLimit"))
}
}
然后只需为每种聚合类型调用方法即可:
var input = new List<Aggregate> {
new Aggregate() {fieldName = "Value",Count = 5,Min = 2,Max = 3 },
new Aggregate() {fieldName = "HighLimit",Count = 6,Min = 5,Max = 8 },
new Aggregate() {fieldName = "LowLimit",Count = 2,Min = 9,Max = 15 } };
List<KpiValue> values = new List<KpiValue>();
values.Add(BuildKpiValue(AggregationType.Count, input, agg => agg.Count));
values.Add(BuildKpiValue(AggregationType.Min, input, agg => agg.Min));
values.Add(BuildKpiValue(AggregationType.Max, input, agg => agg.Max));
// And so on for the other ones