需要以相同方式处理的多种方法

时间:2008-11-10 13:43:31

标签: c# delegates

在我正在编写的一篇C#中,我需要以相同的方式处理具有相同签名的多个方法。此外,将来可能会有更多这些方法。我没有反复重复同样的逻辑,而是想到了以下几点:

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);
   }
}

我认为这有一些很好的功能,但它也有点过于引导和混淆。

你能否感谢更好的方法呢?

btw:

  • 它不需要是交易的。
  • strFailure不会隐藏它包装的异常 完全在必要时

感谢。

4 个答案:

答案 0 :(得分:9)

为什么不使用foreach循环而只是休息? (我已在此处将cleanStep重命名为CleanStep以获得常规性 - 我建议您也这样做。)

foreach(CleanStep step in steps)
{
    string failureText;
    if (!step(build, out failureText))
    {
        logger.Write(LogTypes.Error, strFailure);
        break;
    }
}

请注意,这也遵守IEnumerator<T>的合同,而当前代码不会{ - 1}}自动调用foreachDispose实现IEnumerator<T>。在这种情况下,它不会成为问题,但使用迭代器块disposal is used to execute finally blocks

答案 1 :(得分:2)

您的解决方案既直接又容易理解。我认为没有理由以另一种方式这样做:)

我唯一建议的是用foreach循环替换你的迭代器并打破错误。

答案 2 :(得分:0)

重新混淆 - 好的foreach可能会更加清晰(加上它Dispose()枚举器,你没有这样做。

实际上,“params cleanStep []目标”可能会有所帮助:

static bool RunTargets(params cleanStep[] targets)
{
    // detail as per Jon's post
}

然后你可以打电话:

bool foo = RunTargets(WriteReadme, DeleteFiles,
              TFSHelper.DeleteLabel, TFSHelper.DeleteBuild);

答案 3 :(得分:0)

我会返回一个Exception对象而不是一个字符串。由于异常通常具有全局策略,因此我会编写一些异常扩展。现在你得到:

static Exception Run( this IEnumerable<Step> steps) {
   return 
       steps
       .FirstOrDefault( (step) => step( build ) != null )
       .LogIfFailure();  //or .ThrowIfFailure()
}

扩展名:

public static class ExceptionExtensions {
    private static logger = new Logger();

    public static Exception LogIfFailure( this Exception e ) {
        if( e != null )
            logger.Write( e.Message );
        return e;
    }
    public static Exception ShowDialogIfFailure( this Exception e ) {
        if( e != null )
            MessageBox.Show( e.Message );
        return e;
    }
    public static void ThrowIfFailure( this Exception e ) {
        if( e != null )
            Throw( e );
    }
}