使用通用函数清理代码,以防止重复代码 C#
Clean code with generic func, to prevent repetitive code C#
这段代码运行良好,但在我看来,使用通用函数可以做得更优雅,但我现在不知道该怎么做。
太大且重复
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;
}
});
提前致谢
乔丽妮丝
您可以使用以下方法简化此操作:
(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);
}
});
这不是一个非常容易简化的代码块。如果 BugTask
和 Bug
.
有一个共同的基础类型会更容易
目前你可以这样做:
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);
}
}
这段代码运行良好,但在我看来,使用通用函数可以做得更优雅,但我现在不知道该怎么做。
太大且重复
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;
}
});
提前致谢
乔丽妮丝
您可以使用以下方法简化此操作:
(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);
}
});
这不是一个非常容易简化的代码块。如果 BugTask
和 Bug
.
目前你可以这样做:
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);
}
}