【问题标题】:Same catch code for many methods许多方法的相同捕获代码
【发布时间】:2022-03-24 19:50:28
【问题描述】:

我有几个 C# 方法,我想将它们包装在一个 try-catch 块中。每个函数都有相同的 catch 逻辑。有没有一种优雅的方法可以为这些函数中的每一个添加一个装饰器,以便它们都用相同的 try/catch 块包装?我不想将 try/catch 块添加到所有这些函数中。

例子:

public void Function1(){
   try {
     do something
   }catch(Exception e) {
      //a BUNCH of logic that is the same for all functions
   }
}

public void Function2() {
   try {
     do something different
   }catch(Exception e) {
      //a BUNCH of logic that is the same for all functions
   }
}

【问题讨论】:

  • 你能显示你的代码吗...
  • 为什么不尝试/捕获每个并将异常发送到一个通用静态函数?
  • 使用AOP 例如以下代码:rhyous.com/2012/06/15/… 代码就像向函数添加属性一样简单。 stackoverflow.com/questions/4999144/…
  • @JoelEtherton 我该怎么做,你有例子吗?
  • 您为什么不让您的异常冒泡并由全局异常处理程序处理(记录)?

标签: c# .net


【解决方案1】:

对此的一些功能性解决方案怎么样?请注意,我不会吞下异常并使用 throw; 语句,这将重新引发异常,并保持其原始堆栈跟踪。不要默默吞下异常——这被认为是一种非常糟糕的做法,而且调试代码会变得很糟糕。

void Main()
{
    WrapFunctionCall( () => DoSomething(5));
    WrapFunctionCall( () => DoSomethingDifferent("tyto", 4));
}

public void DoSomething(int v){ /* logic */}

public void DoSomethingDifferent(string v, int val){ /* another logic */}

public void WrapFunctionCall(Action function) 
{
    try
    {
        function();
    }
    catch(Exception e)
    {
         //a BUNCH of logic that is the same for all functions
         throw;
    }
}

如果你需要返回一些值,WrapFunctionCall 方法的签名会改变

void Main()
{
    var result = WrapFunctionCallWithReturn( () => DoSomething(5));
    var differentResult = WrapFunctionCallWithReturn( () => DoSomethingDifferent("tyto", 4));
}

public int DoSomething(int v){ return 0; }

public string DoSomethingDifferent(string v, int val){ return "tyto"; }

public T WrapFunctionCallWithReturn<T>(Func<T> function) 
{
    try
    {
        return function();
    }
    catch(Exception e)
    {
        //a BUNCH of logic that is the same for all functions
        throw;
    }
}

【讨论】:

  • 谢谢!你的代码很有用!我确实遇到了一个问题,如果所有函数(WrapFunctionCallWithReturn 除外)都采用 ref 参数,则会导致错误:“不能在匿名方法中使用 ref 或 out 参数......”。我们通过临时解决它,然后在通话后将其分配回来;有没有办法将此解决方案与 ref 或 out 参数一起使用?
  • 和异步?你喜欢哪个:var result = await WrapFunctionCallWithReturn( () =&gt; DoSomething(5));var result = WrapFunctionCallWithReturn( () =&gt; await DoSomething(5));
  • 我明白了:需要var result = await WrapFunctionCallWithReturn( () =&gt; DoSomething(5)); - await 必须在 try catch 内
  • 节省了很多时间!
  • 完全不相关,但是:“tyto”作为占位符字符串对您有任何价值还是只是随机字母? (这是一个借口说'谢谢你的回答!'顺便说一句)
【解决方案2】:

这是乔尔·埃瑟顿 (Joel Etherton) 的评论,意译为答案。请注意,这不是最佳解决方案(请参阅 Ilya Ivanov 的答案以获得更好的解决方案)。
但这很简单,如果我正确阅读了您的问题,那正是您所要求的:

void errorHandling(Exception e)
{
  // Your BUNCH of logic
}

public void Function1(){
   try {
     do something
   }catch(Exception e) {
      errorHandling(e);
   }
}

public void Function2() {
   try {
     do something different
   }catch(Exception e) {
      errorHandling(e);
   }
}

【讨论】:

    猜你喜欢
    • 2021-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多