【问题标题】:Try/Catch - back to original tryTry/Catch - 回到最初的尝试
【发布时间】:2011-04-14 14:59:40
【问题描述】:

让我们看看这个简单的 try/catch 示例...

try
{
    // User inputs path of a file
    if(!ValidPath)
        throw new InvalidPathException();
}
catch InvalidPathException e
{
    // Log error
    // Re-throw the error.
    throw;     
}

几个问题。两者可能都是简单的答案。

  1. 在 catch 中的 throw 是否会返回并检查下一个 catch,然后是下一个,依此类推?
  2. 有没有办法回到原来的尝试?还是那是糟糕的编程习惯?

【问题讨论】:

标签: c# exception-handling try-catch


【解决方案1】:
  1. 是的,catch 块中的 throw 语句将被任何包装器/下一个 catch 块重新捕获。

  2. 使用 Basic Goto:like 语句修改程序流是一种不好的编程习惯,因此不建议返回原始代码块(这也是不切实际的)。此外,您总是尝试在异常发生位置附近处理异常,因为调试器输出和堆栈跟踪将提供更多信息。

【讨论】:

  • It C# 使用goto 语句从外部进入块(例如try 块)实际上是非法的。所以这不仅仅是一种糟糕的编程习惯。
  • 修改代码流并非不可能,但几乎不切实际,所以是的,你是对的。
  • 嗯...您执行类似while(condition){try{ do stuff} catch(){ } } 的操作,但您需要小心不要陷入无限循环。不完全是“try-catch-retry”,但你可以到达那里。
【解决方案2】:

每个 try 块可以有多个 catch,但只会使用一个。它将捕获最接近的异常。如果您随后抛出异常,它将完全离开这个 try 块,并且只有周围的 catch 才能处理重新抛出的异常。

【讨论】:

    【解决方案3】:

    1.catch中的throw是否返回并检查下一个catch,然后是下一个,以此类推?

    只有第一个匹配任何 try 块中的异常的 catch 块才会被选中。如果 catch 块重新抛出异常,则将其向上传播到外部 try/catch 块(如果有),或向上传播到调用堆栈中的任何其他 try/catch 块。 (它不会被同一个 try/catch 块中的另一个 catch 块捕获。)

    2.有没有办法回到原来的尝试?还是那是不好的编程习惯?

    在 C# 中,您无法返回引发异常的位置,如果这是您所要求的。如果您想再次执行整个 try 块,则只需将其放入循环中即可。但是,这要求您不要重新抛出异常,因为这会将执行发送到方法之外。

    有关重试 try 块的示例,请参阅this question 的答案。

    【讨论】:

      【解决方案4】:
      1. catch 中的 throw 是否会返回并检查下一个 catch,然后是下一个,依此类推?

        Ans: 不,它没有。仅捕获块。

      2. 有没有办法回到原来的尝试?还是那是不好的编程习惯?

        Ans:是的,很少有不同的策略/技巧。

      参考 1:Try-catch every line of code without individual try-catch blocks

      例子:

      public delegate void VoidDelegate();
      
      public static class Utils
      {
        public static void Try(VoidDelegate v) {
          try {
            v();
          }
          catch {}
        }
      }
      
      Utils.Try( () => WidgetMaker.SetAlignment(57) );
      Utils.Try( () => arrayname["Title"] = txtTitle.Text );
      Utils.Try( () => objectname.Season(true, false) );
      Utils.Try( () => (Session["CasseroleTracker"]).Seasoned = true );
      

      另一种方法是使用GOTO statement:

      参考 2:http://social.msdn.microsoft.com/Forums/en-US/Vsexpressvcs/thread/2294d2ce-e6ae-4152-b022-61aa2ae9372d/

      另一种方法是On Error Resume Next

      参考 3:http://msdn.microsoft.com/en-us/library/5hsw66as.aspx

      【讨论】:

      • 您不能从块外转到 try 块内的标签。错误是 Visual Basic。
      • @recursive:您可以从同一个 catch 转到 try 块内的标签。你不了解问题和我的回答,也不知道细节。查看此实际手册:msdn.microsoft.com/en-us/library/69whc95c%28v=vs.80%29.aspx
      • 您提供的是指向有关 Visual Basic 而非 C# 的文档的链接。我真的试过了。编译时错误消息是这样的:在 goto 语句的范围内没有这样的标签“asdf”。
      【解决方案5】:
      var anyway = true;
      while(anyway)
      {
      try
      {
      do somthing
      ...
      ...
      ...
      if no errors anyway = false
      }
      catch
      {
         somthing wrong!
      }
      }
      

      ;)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-12
        • 1970-01-01
        • 1970-01-01
        • 2010-11-23
        • 2010-09-12
        • 1970-01-01
        相关资源
        最近更新 更多