【问题标题】:How to catch all exceptions at class level in CSharp?如何在 CSharp 的类级别捕获所有异常?
【发布时间】:2014-03-13 11:19:09
【问题描述】:

我有这样的课:

class SampleRepositoryClass
{
    void MethodA()
    {
        try
        {
            //do something
        }
        catch(Exception ex)
        {
            LogError(ex);
            throw ex;
        }        
    }

    void MethodB(int a, int b)
    {
        try
        {
            //do something
        }
        catch(Exception ex)
        {
            LogError(ex);
            throw ex;
        }
    }

    List<int> MethodC(int userId)
    {
        try
        {
            //do something
        }
        catch(Exception ex)
        {
            LogError(ex);
            throw ex;
        }
    }
}

在上面的示例中,您可以看到在每个方法(MethodA、MethodB、MethodC)中都有 try...catch 块来记录错误,然后抛出到更高级别。

想象一下,当我的 Repository 类可能有一百多个方法并且在每个方法中我都有 try...catch 块时,即使只有一行代码。

现在,我的目的是减少这些重复的异常记录代码,并在类级别而不是方法级别记录所有异常。

【问题讨论】:

  • 只有 aspect-oriented programming tools/weavers like PostSharp 可以帮助你。对了,一个类有一百多个方法?那只是……糟糕。至少从我的角度来看。而且绝对可怕。
  • 确实如此,但我的业务和存储库类有很多方法,这使得这些类过于繁重。实际上,一个类中方法的数量取决于业务规则的复杂程度或您要执行的操作的数量。
  • 不要使用“throw ex;”因为那会破坏你宝贵的调用堆栈。只需写“投掷”;并且异常中的信息将被保留。话虽如此,我想指出,除非您知道如何处理异常,否则不应捕获异常。参考:stackoverflow.com/questions/730250/…
  • @Patrik- 我知道我应该只写“投掷”。您的建议是执行错误处理的最佳实践。但我的情况不同,我想在单个类级别处理所有类方法异常。对于 A 类中的所有方法,必须只有一个地方来处理和记录 A 类的任何方法中发生的错误。

标签: c# exception exception-handling


【解决方案1】:

既然有 免费 Post Sharp Express 这样的事情,为什么还要重新发明轮子。 就像添加PostSharp.dll 作为对您项目的引用一样简单。 完成此操作后,您的存储库将如下所示:

[Serializable]
class ExceptionWrapper : OnExceptionAspect
{
    public override void OnException(MethodExecutionArgs args)
    {
        LogError(args.Exception);
        //throw args.Exception;
    }
}

[ExceptionWrapper]
class SampleRepositoryClass
{
    public void MethodA()
    {
        //Do Something
    }

    void MethodB(int a, int b)
    {
        //Do Something
    }

    List<int> MethodC(int userId)
    {
        //Do Something
    }
}

在类上添加ExceptionWrapper 属性,确保所有属性和方法都封装在try/catch 块中。 catch 中的代码将是您放入 ExceptionWrapper 中的覆盖函数 OnException() 中的代码。

您也不需要编写代码来重新抛出。如果提供了正确的流行为,也可以自动重新抛出异常。请查看相关文档。

【讨论】:

    【解决方案2】:

    你太保守了。不要过度使用try..catch,只在需要的地方捕获它。

    在这种情况下,请考虑捕获因在课堂外与课堂互动而引发的异常。记住异常会被传播。

    【讨论】:

      【解决方案3】:

      使用Policy Injection Application Block、Castle、Spring.NET 等库。这些库允许您将行为注入异常捕获。

      【讨论】:

      • 能否在不使用任何其他库(策略注入应用程序块、Castle 或 Spring.NET)的情况下分享一些示例代码?
      • 不幸的是,这些库实现了代理设计模式并处理了大量反射等。如果我跳过这个管道,我将不得不编写很多代码......
      【解决方案4】:

      只需在 App.xaml.cs 中实现 DispatcherUnhandledException;它将处理您的所有异常;

          public partial class App : Application
          {
              protected override void OnStartup(StartupEventArgs e)
              {
                  DispatcherUnhandledException += App_DispatcherUnhandledException;
              }
              void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
              {
                  LogError(e);
      // MessageBox.Show(e.Exception.Message);
                  e.Handled = true;
              }
      

      【讨论】:

      • 对不起 Jannesary,我想在 BAL 或 DAL 的类库中执行它。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      相关资源
      最近更新 更多