用通用函数清理代码,以防止重复代码C#

时间:2017-02-15 10:57:30

标签: c# generics repeat

这段代码工作正常,但在我看来,使用泛型函数可以做得更优雅,但我现在不知道如何做。

是大而重复的

result.ForEach(ids =>
             {
                 switch (ids.TaskType.ToUpper())
                 {
                     case "BUGS":
                         if (propertyName == "SpentTimeHours")
                         {
                             TotalBugs += GraphTable
                                          ._Bugs
                                          .Where(x => x.Aid == ids.Aid)
                                          .Select(x => x.SpentTimeHours)
                                          .FirstOrDefault() ?? 0;
                         }
                         if (propertyName == "RemainingTimeHours")
                         {
                             TotalBugs += GraphTable
                                          ._Bugs
                                          .Where(x => x.Aid == ids.Aid)
                                          .Select(x => x.RemainingTimeHours)
                                          .FirstOrDefault() ?? 0;
                         }
                         break;
                     case "TASKS_BUGS":
                         if (propertyName == "SpentTimeHours")
                         {
                             TotalTaskBugs += GraphTable
                                              ._BugTask
                                              .Where(x => x.Aid == ids.Aid)
                                              .Select(x => x.SpentTimeHours)
                                              .FirstOrDefault() ?? 0;
                         }
                         if (propertyName == "RemainingTimeHours")
                         {
                             TotalTaskBugs += GraphTable
                                             ._BugTask
                                             .Where(x => x.Aid == ids.Aid)
                                             .Select(x => x.RemainingTimeHours)
                                             .FirstOrDefault() ?? 0;
                         }
                         break;
                 }
             });

提前致谢

Jolynice

2 个答案:

答案 0 :(得分:1)

您可以使用以下内容简化此操作:

(ids =>
{
    Func<Bug, int> selector = null;
    IEnumerable<Bug> source = null;
    Action<int> incrementor = null;

    switch (ids.TaskType.ToUpper())
    {
        case "BUGS":
            source = GraphTable._Bugs;
            incrementor = i => TotalBugs + i;   
            break;
        case "TASKS_BUGS":
            source = GraphTable._BugTask;
            incrementor = i => TotalTaskBugs + i; 
            break;
        }
    }

    if (propertyName == "SpentTimeHours")
    {
        selector = b => b.SpenTimeHours;
    }
    else if (propertyName == "RemainingTimeHours")
    {
        selector = b => b.RemainingTimeHours;
    }

    if (selector != null && source != null)
    {
         Incrementor(source.Where(x => x.Aid == ids.Aid)
                           .Select(selector)
                           .FirstOrDefault() ?? 0);
    }
});

答案 1 :(得分:0)

这不是一个简单易用的代码块。如果BugTaskBug存在基于公共类型,则会更容易。

目前您可以这样做:

var operations = new Operation[]
{
    new BugOperation() { TaskType = "BUGS", PropertyName = "SpentTimeHours", Source = GraphTable._Bugs, Select = x => x.SpentTimeHours, Incremement = v => TotalBugs += v },
    new BugOperation() { TaskType = "BUGS", PropertyName = "RemainingTimeHours", Source = GraphTable._Bugs, Select = x => x.RemainingTimeHours, Incremement = v => TotalBugs += v  },
    new BugTaskOperation() { TaskType = "TASKS_BUGS", PropertyName = "SpentTimeHours", Source = GraphTable._BugTask, Select = x => x.SpentTimeHours, Incremement = v => TotalTaskBugs += v  },
    new BugTaskOperation() { TaskType = "TASKS_BUGS", PropertyName = "RemainingTimeHours", Source = GraphTable._BugTask, Select = x => x.RemainingTimeHours, Incremement = v => TotalTaskBugs += v  },
};

var query =
    from ids in result
    from operation in
        operations
            .Where(x => x.TaskType == ids.TaskType.ToUpper())
            .Where(x => propertyName == x.PropertyName)
            .Take(1)
    where operation != null
    select new { ids, operation }

foreach (var x in query)
{
    x.operation.Update(x.ids.Aid);
}

这意味着您在一个位置(operations数组)中获得了特定于每个组合的代码,其余代码纯粹是执行。

您需要这些支持课程:

private abstract class Operation
{
    public string TaskType;
    public string PropertyName;
    public Action<double> Incremement;

    public abstract void Update(long aid);
}

private class BugOperation : Operation
{
    public IEnumerable<Bug> Source;
    public Func<Bug, double?> Select;

    public override void Update(long aid)
    {
        this.Incremement(
            this.Source
                .Where(x => x.Aid == aid)
                .Select(this.Select)
                .FirstOrDefault() ?? 0);
    }
}

private class BugTaskOperation : Operation
{
    public IEnumerable<BugTask> Source;
    public Func<BugTask, double?> Select;

    public override void Update(long aid)
    {
        this.Incremement(
            this.Source
                .Where(x => x.Aid == aid)
                .Select(this.Select)
                .FirstOrDefault() ?? 0);
    }
}