Bre*_*ick 9 c# linq refactoring
我试图弄清楚如何很好地重构这个LINQ代码.此代码和其他类似代码在同一文件和其他文件中重复.有时被操纵的数据是相同的,有时数据会发生变化,逻辑也会保持不变.
以下是在不同对象的不同字段上运行的重复逻辑的示例.
public IEnumerable<FooDataItem> GetDataItemsByColor(IEnumerable<BarDto> dtos)
{
double totalNumber = dtos.Where(x => x.Color != null).Sum(p => p.Number);
return from stat in dtos
where stat.Color != null
group stat by stat.Color into gr
orderby gr.Sum(p => p.Number) descending
select new FooDataItem
{
Color = gr.Key,
NumberTotal = gr.Sum(p => p.Number),
NumberPercentage = gr.Sum(p => p.Number) / totalNumber
};
}
public IEnumerable<FooDataItem> GetDataItemsByName(IEnumerable<BarDto> dtos)
{
double totalData = dtos.Where(x => x.Name != null).Sum(v => v.Data);
return from stat in dtos
where stat.Name != null
group stat by stat.Name into gr
orderby gr.Sum(v => v.Data) descending
select new FooDataItem
{
Name = gr.Key,
DataTotal = gr.Sum(v => v.Data),
DataPercentage = gr.Sum(v => v.Data) / totalData
};
}
Run Code Online (Sandbox Code Playgroud)
任何人都有很好的重构方法吗?
mqp*_*mqp 11
像这样的东西:
public IEnumerable<FooDataItem> GetDataItems<T>(IEnumerable<BarDto> dtos,
Func<BarDto, T> groupCriteria,
Func<BarDto, double> dataSelector,
Func<T, double, double, FooDataItem> resultFactory)
{
var validDtos = dtos.Where(d => groupCriteria(d) != null);
double totalNumber = validDtos.Sum(dataSelector);
return validDtos
.GroupBy(groupCriteria)
.OrderBy(g => g.Sum(dataSelector))
.Select(gr => resultFactory(gr.Key,
gr.Sum(dataSelector),
gr.Sum(dataSelector) / totalNumber));
}
Run Code Online (Sandbox Code Playgroud)
在您的示例中,您可以这样称呼它:
GetDataItems(
x => x.Color, // the grouping criterion
x => x.Number, // the value criterion
(key, total, pct) =>
new FooDataItem {
Color = key, NumberTotal = total, NumberPercentage = pct });
Run Code Online (Sandbox Code Playgroud)
如果您更改FooDataItem为更通用,那将更容易.