避免有细微差别的重复循环
本文关键字:循环 | 更新日期: 2023-09-27 18:09:33
我正在做一个项目,我注意到很多重复的代码,我想把重复的代码合并到一个方法中。
这是重复代码的一个示例:
foreach (var glider in gliders)
{
List<PriceDataModel_New> bestPrices = PriceService.GetBestPrices(prices, glider.Value.No, string.Empty, string.Empty, string.Empty, 1);
var priceGroups = bestPrices.GroupBy(p => p.SalesCode);
var salesCodePrice = priceGroups.ToDictionary(k => k.Key, v => v.First());
AddEmptyines(fieldMapping, lines);
var last = lines.Last();
foreach (var keyValuePair in fieldMapping.Postions)
{
int index = keyValuePair.Key;
var key = keyValuePair.Value.InternalHeading;
InsertInLines(last, key, index, "CODE_Id", modelNo + "_" + glider.Value.No);
InsertInLines(last, key, index, "ItemId", glider.Value.No);
InsertInLines(last, key, index, "CODE_OptionalName", (glider.Value.ComponentType + " " + glider.Value.ProductFamily).ToLower());
InsertInLines(last, key, index, "Attr_Family name", family);
InsertInLines(last, key, index, "CODE_IsOptional", "true");
InsertInLines(last, key, index, "Model", modelNo);
InsertInLines(last, key, index, "CODE_OptionalInfo", glider.Value.Size.ToLower());
if (AddToLinePrice(salesCodePrice, keyValuePair.Value.InternalHeading, index, last))
continue;
}
}
//AppendLines(seatPads, prices, lines, fieldMapping, "", modelNo, family, "linking.Value.SimpleMaterial", "");
foreach (var seatPad in seatPads)
{
List<PriceDataModel_New> bestPrices = PriceService.GetBestPrices(prices, seatPad.Value.No, seatPad.Value.Variant.Substring(0, 3), string.Empty, string.Empty, 1);
var priceGroups = bestPrices.GroupBy(p => p.SalesCode);
var salesCodePrice = priceGroups.ToDictionary(k => k.Key, v => v.First());
AddEmptyines(fieldMapping, lines);
var last = lines.Last();
foreach (var keyValuePair in fieldMapping.Postions)
{
int index = keyValuePair.Key;
var key = keyValuePair.Value.InternalHeading;
InsertInLines(last, key, index, "CODE_Id", modelNo + "_" + seatPad.Value.No);
InsertInLines(last, key, index, "ItemId", seatPad.Value.No);
InsertInLines(last, key, index, "CODE_OptionalName", seatPad.Value.ModelNo.ToLower());
InsertInLines(last, key, index, "Attr_Family name", family);
InsertInLines(last, key, index, "CODE_IsOptional", "true");
InsertInLines(last, key, index, "Model", modelNo);
InsertInLines(last, key, index, "CODE_OptionalInfo", seatPad.Value.UpholsteryFabric.ToLower() + " black");
if (AddToLinePrice(salesCodePrice, keyValuePair.Value.InternalHeading, index, last))
continue;
}
}
//AppendLines(linkingDevices, prices, lines, fieldMapping, "", modelNo, family, "linking.Value.SimpleMaterial", "");
foreach (var linking in linkingDevices)
{
List<PriceDataModel_New> bestPrices = PriceService.GetBestPrices(prices, linking.Value.No, string.Empty, string.Empty, string.Empty, 1);
var priceGroups = bestPrices.GroupBy(p => p.SalesCode);
var salesCodePrice = priceGroups.ToDictionary(k => k.Key, v => v.First());
AddEmptyines(fieldMapping, lines);
var last = lines.Last();
foreach (var keyValuePair in fieldMapping.Postions)
{
int index = keyValuePair.Key;
var key = keyValuePair.Value.InternalHeading;
InsertInLines(last, key, index, "CODE_Id", modelNo + "_" + linking.Value.No);
InsertInLines(last, key, index, "ItemId", linking.Value.No);
InsertInLines(last, key, index, "CODE_OptionalName", linking.Value.ComponentType.ToLower());
InsertInLines(last, key, index, "Attr_Family name", family);
InsertInLines(last, key, index, "CODE_IsOptional", "true");
InsertInLines(last, key, index, "Model", modelNo);
InsertInLines(last, key, index, "CODE_OptionalInfo", linking.Value.SimpleMaterial);
if (AddToLinePrice(salesCodePrice, keyValuePair.Value.InternalHeading, index, last))
continue;
}
}
上面的foreach循环只有几行不同。我想不出怎么把它做成通用的。我已经尝试了Reflection, Func<>和delegate,任何建议都是非常欢迎的。
为滑翔机、座椅垫和链接设备对象实现一个类似于下面的接口:
public interface IProduct
{
string No { get; }
string CodeName { get; }
string Family { get; }
string ModelNo { get; }
string CodeInfo { get; }
IDictionary<string, string> FieldMapping { get; }
}
然后创建一个泛型函数,如:
private void Generic<T>(IEnumerable<T> products, string modelNo)
where T: IProduct
接受产品之外的任何内容(如输入中的modelNo),并输入特定于产品的内容(如果'product'不太合适,请更改名称)。
可选地,我会将Fieldmapping字典更改为平展属性,以便这样做有意义(但我不确定潜在的复杂性):
public interface IProduct
{
string No { get; }
string CodeName { get; }
string Family { get; }
string ModelNo { get; }
string SalesCode { get; }
string CodeInfo { get; }
IEnumerable<IProductAttribute> Attributes { get; }
}
public interface IProductAttribute
{
string InternalHeading { get; }
int Index { get; } //not sure what this is for.
}
首先,为glider, seatPad和链接子类创建一个基类。
提取内部foreach的主体并将其移动到自己的方法中。传递的参数应该是基类类型,这样代码就可以适用于所有子类型。
嗯,很难提出最好的解决方案,因为这是非常主观的…Func<>
可能适用于差异很小的情况或者只有一些差异的情况。
在这里使用一个公共接口(如果你不想改变原始对象,可以使用一些适配器/facade/bridge),可能会更合适。
或者,您也可以创建另一个类,它将具有所需的字段,并简单地将原始数据转换为新格式。
哪个解决方案更有意义?那就由你来评价了。
类适配器模式