11

我对周围的代码感到厌烦,像这样尝试捕获..

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

我想要类似的东西

SurroundWithTryCatch(MyMethod)

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

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

还有其他有效的想法吗?

4

7 回答 7

24

首先,听起来您可能过于频繁地使用 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 语句。)

于 2008-11-11T06:35:57.973 回答
4

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

于 2008-11-11T08:03:23.973 回答
3

您可以尝试改用一些空值验证。我可以举一个 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...
于 2008-11-11T06:09:30.897 回答
2

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

于 2008-11-11T06:10:33.373 回答
2

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

于 2008-11-11T07:41:09.823 回答
0

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

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

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

但是,我认为您真正想要的是一种具有良好闭包支持的语言。使用闭包,做你想做的事非常容易。

于 2008-11-11T06:34:44.963 回答
0

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

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

于 2008-11-11T09:40:46.383 回答