避免有细微差别的重复循环

本文关键字:循环 | 更新日期: 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),可能会更合适。

或者,您也可以创建另一个类,它将具有所需的字段,并简单地将原始数据转换为新格式。

哪个解决方案更有意义?那就由你来评价了。

类适配器模式