【问题标题】:Try catch finally: Do something if no exception is thrownTry catch finally:如果没有抛出异常则做某事
【发布时间】:2012-05-03 12:30:17
【问题描述】:

我想知道,有没有办法只在没有抛出异常的情况下执行一个块?

我能想到的最好的是:

bool exception = false;
try{
    // something
}catch(Exception e){
    exception = true;
}finally{
    if(!exception){
        // i can do what i want here
    } 
}

有没有更好的办法?

【问题讨论】:

  • 你的 try 块中是否有任何“返回”?
  • 答案有18票,问题1票?
  • @MattHickford :很好(或至少是正确)回答了一个不太好的问题,问题出在哪里?

标签: c# try-catch


【解决方案1】:

当然有:把它放在try 块的底部。

try{
    // something
    // i can do what i want here
}catch(Exception e){
    // handle exception
}

这并不完全等同于您的原始代码,因为如果“您想要的”抛出,异常将在本地捕获(这不会发生在您的原始方案中)。这是您可能关心也可能不关心的事情,而且不同的行为也很有可能是正确的。

如果您想恢复旧的行为,您也可以使用这个不需要finally 的变体,只是为了编写“如果没有例外”条件:

var checkpointReached = false;
try{
    // something
    checkpointReached = true;
    // i can do what i want here
}catch(Exception e){
    if (checkpointReached) throw; // don't handle exceptions after the checkpoint
    // handle exception
}

【讨论】:

  • 问题是,如果你重复这种模式,你会得到 try-catch 重叠。因此,仅在预期很少有例外情况下才建议使用它。
  • @dystroy:不明白你的意思,你能详细说明一下吗?
  • 如果你使用这个模式一次,然后在“I can do etc.”需要添加另一个try catch,你必须覆盖它。再做几次,你的代码就会非常复杂。我敢肯定你有足够的经验,所以一次你会把你的代码分成不同的功能,但我觉得必须指出这一点(这就是我在回答中指出“返回”模式的原因)。
  • @dystroy:嵌套的 try/catch 本身就是一个问题,它不取决于在这里选择哪种方法。我不能真正考虑 return 一个实用的解决方案,因为它方式过多地假设了该方法的作用,因此它不适用于一般情况。
【解决方案2】:

你不需要 finally 子句。

解决方案:

bool exception = false;
try{
    // something
}catch(Exception e){
    exception = true;
}
if(!exception){
     // u can do what u want here
} 

通常你会在你的 catch 子句中有一个 return ,这样你甚至不必测试:

try{
    // something
}catch(Exception e){
   // do things
   return;
}
// u can do what u want here

或(取决于用例,通常不太清楚,特别是如果您预期有多个异常 - 您不想进行 try-catch 嵌套...):

try{
    // something
    // u can do what u want here
}catch(Exception e){
   // do things
}

【讨论】:

  • 我的母语是英语(和工程师),但我不得不查找“重叠”——“像鱼鳞一样重叠”。我觉得这个词在法语中比较普通,google把它翻译成“嵌套”。
  • @Spike0xff 我改了字。你是对的,它不是最好的选择
【解决方案3】:

你能否构造你的代码,使 doSomething 是块中的最后一条语句并且它不会抛出?

bool exception = false;
try{
  // something
  doSomething();
} catch {
}
finally {
}

【讨论】:

  • @Jeff Fosterno 需要 finally 在这里阻止。
  • 我假设有一些样板清理代码希望始终运行。如果不是,那你肯定是对的,这是多余的。
【解决方案4】:

是的,有: 把它放在 try 块的末尾:)

【讨论】:

    【解决方案5】:

    不——你所拥有的可能是 C# 中最好的方法。

    这是假设:

    • 您不希望 “我可以在这里做我想做的事” 代码在 try 块的底部运行。 (可能是因为您不希望该代码中的异常由主 catch 块处理。)
    • 您不希望“我可以在这里做我想做的事” 代码完全在try...catch...finally 结构之外运行。 (可能是因为您希望该代码在位于 finally 块内的其他代码之前运行。)

    【讨论】:

      【解决方案6】:

      虽然您的代码没有任何问题,但这是不必要的。只需将您希望执行的代码放在 try 块的底部即可:

      try {
          ...
          // No errors to this point, run what you wanted to run in the finally.
      }
      catch(Exception e) {
          ...
      }
      

      【讨论】:

        【解决方案7】:

        我相信您正在尝试中寻找尝试:

        try{
            // something
        
            try{
                // something else not interfering with first try
            } catch(Exception innerEx){
                // something else threw this innerEx
            }
        
        }catch(Exception outerEx){
            // something threw this outerEx
        }
        

        虽然这通常被认为是不好的做法,但我更喜欢它而不是标志版本。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-03-28
          • 1970-01-01
          • 2011-05-17
          • 2010-11-09
          • 1970-01-01
          • 1970-01-01
          • 2017-10-03
          相关资源
          最近更新 更多