【问题标题】:How to get rid of try catch?如何摆脱try catch?
【发布时间】:2010-09-21 18:17:36
【问题描述】:

我厌倦了像这样 try catch 的周围代码..

try
{
    //some boring stuff
}
catch(Exception ex)
{
    //something even more boring stuff
}

我想要类似的东西

SurroundWithTryCatch(MyMethod)

我知道我可以通过创建一个具有函数确切签名的委托来完成此行为,但是为我的应用程序中的所有方法创建一个委托,这不是一个选项。

我也可以通过注入 IL 代码来做到这一点,但这在性能方面很昂贵,因为它会在我的周围创建一个包装程序集。

还有其他有效的想法吗?

【问题讨论】:

    标签: c# error-handling


    【解决方案1】:

    您可以尝试改用一些空值验证。我可以举一个 LINQ to SQL 的例子:

    var user = db.Users.SingleOrDefault(u => u.Username == 3);
    
    if (user == null)
        throw new ArgumentNullException("User", "User cannot be null.");
    
    // "else" continue your code...
    

    【讨论】:

    • 实际上你永远不应该抛出NullReferenceException。这是为运行时保留的。你可以试试ArgumentNullException
    • 对不起。我匆匆写下。我马上改。谢谢:)
    【解决方案2】:

    也许您通过不同的语法将异常处理视为错误代码?所以不要尝试/抓住。让异常向上传播。

    【讨论】:

      【解决方案3】:

      我不确定 C#,但在 Java 领域,您可以定义所有方法并与之交互,然后将其隐藏在代理对象下。您可以通过定义以下内容来编写更多代码:

      ExceptionCatcher.catchAll(new Runnable() {
        public void run() {
           //run delegate here
           MyMethod();
        }
      });
      

      而 catchAll() 只会调用 runnable 并在其周围包裹一个 try-catch 块。

      但是,我认为您真正想要的是一种很好的语言closure support。使用闭包,做你想做的事非常容易。

      【讨论】:

      • 幸运的是,C# 一种具有良好闭包支持的语言 :) (问题没有说明语言,但可以通过代码和提及 IL 和委托来推断。 )
      【解决方案4】:

      首先,听起来您可能过于频繁地使用 try/catch - 特别是如果您正在捕捉 Exception。 try/catch 块应该是比较少见的;除非你真的能“处理”异常,否则你应该让它冒泡到堆栈的下一层。

      现在,假设您真的确实想要所有这些 try/catch 块,为什么不能选择创建委托?使用匿名方法和 lambda 表达式,以及 System 命名空间中的 Func/Action 委托,基本上几乎没有什么工作要做。你写:

      public void SurroundWithTryCatch(Action action)
      {
          try
          {
              action();
          }
          catch(Exception ex)
          {
              //something even more boring stuff
          }    
      }
      

      然后你的SurroundWithTryCatch(MyMethod) 会正常工作,如果它不需要参数的话。

      或者,如果您不想调用不同的方法,只需编写:

      public void MyMethod()
      {
          SurroundWithTryCatch(() => 
          {
              // Logic here
          });
      }
      

      如果需要从方法返回,可以这样做:

      public int MyMethod()
      {
          return SurroundWithTryCatch(() => 
          {
              // Logic here
              return 5;
          });
      }
      

      使用SurroundWithTryCatch 的通用重载,如下所示:

      public T SurroundWithTryCatch<T>(Func<T> func)
      {    
          try
          {
              return func();
          }
          catch(Exception ex)
          {
              //something even more boring stuff
          }    
      }
      

      这大部分在 C# 2 中也可以,但类型推断对您的帮助不大,您必须使用匿名方法而不是 lambda 表达式。

      不过还是回到开头:尽量少用 try/catch。 (try/finally 应该更频繁,尽管通常写成 using 语句。)

      【讨论】:

      • @Jon 啊,你打败了我..DAM YOU ;)
      【解决方案5】:

      对我来说,我看起来您要求的是面向方面的编程。我认为你应该看看 PostSharp。

      【讨论】:

      • 谢谢,我想这就是我想要的,你在生产代码中使用过这种方法吗?
      【解决方案6】:

      面向方面的编程也可以帮助您,但这可能需要您将库添加到您的项目中,postsharp 在这种情况下会帮助您。 看这个链接http://doc.postsharp.org/1.0/index.html#http://doc.postsharp.org/1.0/UserGuide/Laos/AspectKinds/OnExceptionAspect.html#idHelpTOCNode650988000

      【讨论】:

      • 嘿,这正是我想要的,你有这方面的经验吗?你会推荐使用它而不是经典方式吗?
      • 我只将它用于学习目的,而不是用于实际项目。我个人非常喜欢这个概念。
      【解决方案7】:

      如果您使用的是 Java,就会遇到 RuntimeExceptions,这些异常意味着出现了无法恢复的问题。查一下。从这里开始:http://java.sun.com/docs/books/tutorial/essential/exceptions/runtime.html

      例如,当出现问题时,Spring 的数据访问位会抛出各种 RuntimeExceptions。处理它们是可选的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-28
        • 2013-10-31
        • 2020-10-19
        • 2019-12-01
        相关资源
        最近更新 更多