C# 需要以相同方式处理的多个方法
在我正在编写的一段C代码中,我需要以相同的方式处理几个具有相同签名的方法。将来可能还会有更多的这种方法。我没有反复重复同样的逻辑,而是想到了以下几点:C# 需要以相同方式处理的多个方法,c#,delegates,C#,Delegates,在我正在编写的一段C代码中,我需要以相同的方式处理几个具有相同签名的方法。将来可能还会有更多的这种方法。我没有反复重复同样的逻辑,而是想到了以下几点: private delegate bool cleanStep(BuildData bd, out String strFailure); List<cleanStep> steps = new List<cleanStep>(); steps.Add(WriteReadme); steps.Add(DeleteFile
private delegate bool cleanStep(BuildData bd, out String strFailure);
List<cleanStep> steps = new List<cleanStep>();
steps.Add(WriteReadme);
steps.Add(DeleteFiles);
steps.Add(TFSHelper.DeleteLabel);
steps.Add(TFSHelper.DeleteBuild);
List<cleanStep>.Enumerator enumerator = steps.GetEnumerator();
bool result = true;
while (result && enumerator.MoveNext())
{
result = enumerator.Current.Invoke(build, out strFailure);
if (!result)
{
logger.Write(LogTypes.Error, strFailure);
}
}
我认为这有一些很好的特性,但它也感觉有点过于复杂和模糊
你能想出一个更好的方法吗
顺便说一句:
它不需要是事务性的。
strFailure不会隐藏异常,而是将它们包装起来
必要时完全
谢谢 为什么不使用foreach循环并中断呢?出于惯例,我将cleanStep重命名为cleanStep-我建议您也这样做
foreach(CleanStep step in steps)
{
string failureText;
if (!step(build, out failureText))
{
logger.Write(LogTypes.Error, strFailure);
break;
}
}
请注意,这也遵守IEnumerator的约定,您当前的代码不会这样做—foreach自动调用Dispose,IEnumerator实现IDisposable。在这种情况下这不是问题,但是对于迭代器块,。为什么不使用foreach循环并中断呢?出于惯例,我将cleanStep重命名为cleanStep-我建议您也这样做
foreach(CleanStep step in steps)
{
string failureText;
if (!step(build, out failureText))
{
logger.Write(LogTypes.Error, strFailure);
break;
}
}
请注意,这也遵守IEnumerator的约定,您当前的代码不会这样做—foreach自动调用Dispose,IEnumerator实现IDisposable。在这种情况下,这不是问题,但使用迭代器块,。您的解决方案既简单又易于理解。我看不出有任何理由用另一种方式:
我唯一的建议是用foreach循环替换迭代器,并在出现错误时中断。您的解决方案既简单又易于理解。我看不出有任何理由用另一种方式: 我唯一的建议是用foreach循环替换迭代器,并在出现错误时中断。重新模糊-使用break的foreach可能更清晰,而且它将处理枚举数,而您没有这样做 实际上,params cleanStep[]目标可能有助于:
static bool RunTargets(params cleanStep[] targets)
{
// detail as per Jon's post
}
然后你可以打电话:
bool foo = RunTargets(WriteReadme, DeleteFiles,
TFSHelper.DeleteLabel, TFSHelper.DeleteBuild);
重新模糊-well foreach with break可能更清晰,而且它将处理枚举数,而您没有这样做
实际上,params cleanStep[]目标可能有助于:
static bool RunTargets(params cleanStep[] targets)
{
// detail as per Jon's post
}
然后你可以打电话:
bool foo = RunTargets(WriteReadme, DeleteFiles,
TFSHelper.DeleteLabel, TFSHelper.DeleteBuild);
我将返回一个异常对象而不是字符串。由于异常通常有一个全局策略,所以我将编写一些异常扩展。现在您可以:
static Exception Run( this IEnumerable<Step> steps) {
return
steps
.FirstOrDefault( (step) => step( build ) != null )
.LogIfFailure(); //or .ThrowIfFailure()
}
我将返回一个异常对象而不是字符串。由于异常通常有一个全局策略,所以我将编写一些异常扩展。现在您可以:
static Exception Run( this IEnumerable<Step> steps) {
return
steps
.FirstOrDefault( (step) => step( build ) != null )
.LogIfFailure(); //or .ThrowIfFailure()
}
看起来已经好多了。还学习了有关枚举数处理的新知识。谢谢我对break语句有点反感,但在这里它确实是有意义的。这看起来已经更好了。还学习了有关枚举数处理的新知识。谢谢我对break语句有点反感,但它在这里确实有意义。谢谢,这实际上是我喜欢的特性之一。你可以重构这个函数,但也可以创建列表。谢谢,这实际上是我喜欢的特性之一。你可以重构这个函数,也可以创建列表。谢谢。我喜欢干净的沙发,但当一步失败时它不会停止。我知道我说过它不需要是事务性的,但是当一个步骤失败时,我们甚至不想尝试其余的步骤。谢谢。我喜欢干净的沙发,但当一步失败时它不会停止。我知道我说过它不需要是事务性的,但是当一个步骤失败时,我们甚至不希望它尝试其余的步骤。