C# 嵌套 Try Catch 语句或方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/663710/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 12:23:24  来源:igfitidea点击:

C# Nested Try Catch statements or methods?

c#error-handlingmethods

提问by ghost

Simple best practice question.

简单的最佳实践问题。

Should you nest try catch statements or just use methods.

你应该嵌套 try catch 语句还是只使用方法。

For instance, if you have a method that opens a file does work and closes the file, you would have the open and close outside the try catch, or rather the close in the finally block.

例如,如果您有一个打开文件并关闭文件的方法,那么您将在 try catch 之外打开和关闭,或者更确切地说是在 finally 块中关闭。

Now if your open method fails, the method would assert right? So should your wrap that in a try catch block or should that be called from another method, which in turn as a try catch block?

现在,如果您的 open 方法失败,该方法会断言吗?那么你应该将它包装在一个 try catch 块中还是应该从另一个方法中调用它,而后者又作为一个 try catch 块?

回答by Pontus Gagge

Depends on what you are trying to do, but in most cases, nested try/catches are a sign of an over-complex function (or of a programmer who doesn't quite know how exceptions work!).

取决于你想做什么,但在大多数情况下,嵌套的 try/catch 是一个过于复杂的函数的标志(或者一个不太了解异常如何工作的程序员!)。

In the case of the open file, I'd use an IDisposable holder and a using clause, and so forgo the need of any explicit try/catch.

在打开文件的情况下,我将使用 IDisposable 持有者和 using 子句,因此放弃任何显式 try/catch 的需要。

回答by JaredPar

This is a style question but for me I try to never have more than one level of try/catch/finally nesting in a single method. At the point you hit a nested try, you've almost certainly violated the 1 function = 1 operation principal and should use a second method.

这是一个风格问题,但对我来说,我尝试在单一方法中永远不要有超过一个级别的 try/catch/finally 嵌套。在您进行嵌套尝试时,您几乎可以肯定违反了 1 function = 1 操作原则,应该使用第二种方法。

回答by cgreeno

In the context of a method that opens a file I would use a using statement vs a try catch. The using statement ensures that Dispose is called if an exception occurs.

在打开文件的方法的上下文中,我将使用 using 语句与 try catch。using 语句确保在发生异常时调用 Dispose。

using (FileStream fs = new FileStream(file, FileMode.Open))
{
    //do stuff
}

does the same thing as:

做同样的事情:

FileStream fs;
try
{
     fs = new FileStream(file, FileMode.Open);
     //do Stuff
 }
 finally
 {
        if(fs!=null)
           fs.Dispose();
 }

回答by Brian Ensink

Most of the time I would break up the nested try/catch blocks into functions. But I have sometimes written code to catch and log all uncaught exceptions thrown by my application. But what if the logging code fails? So I have yet another try/catch around that just to prevent the user from seeing the default .NET unhandled exception dialog box. But even this code could very easily be refactored into functions instead of nested try/catch blocks.

大多数情况下,我会将嵌套的 try/catch 块分解为函数。但是我有时会编写代码来捕获和记录我的应用程序抛出的所有未捕获的异常。但是如果日志代码失败怎么办?所以我还有另一个尝试/捕捉,只是为了防止用户看到默认的 .NET 未处理异常对话框。但即使是这段代码也可以很容易地重构为函数而不是嵌套的 try/catch 块。

try
{
    try
    {
        DoEverything(); 
    }
    catch (Exception ex)
    {
        // Log the exception here
    }
}
catch (Exception ex)
{
    // Wow, even the log is broken ...
}

回答by Charlie Flowers

Now that we have lambdas and type inference and some other stuff, there's an idiom that is common in other languages which now makes a lot of sense in C#. Your example was about opening a file, doing something to it, and then closing it. Well, now, you can make a helper method which opens a file, and also takes care of making sure to close / dispose / clean up, but calls out to a lambda you provide for the "do stuff" portion. This will help you get the complicated try/catch/finally dispose/cleanup stuff right in one place, and then use it over and over.

现在我们有了 lambda 表达式和类型推断以及其他一些东西,有一个在其他语言中很常见的习语,现在在 C# 中很有意义。你的例子是关于打开一个文件,对它做一些事情,然后关闭它。好吧,现在,您可以创建一个帮助方法来打开文件,并确保关闭/处置/清理,但调用您为“做事”部分提供的 lambda。这将帮助您将复杂的 try/catch/finally dispose/cleanup 东西放在一个地方,然后一遍又一遍地使用它。

Here's an example:

下面是一个例子:

public static void ProcessFile(string filePath, Action<File> fileProcessor)
{
  File openFile = null;

  try
  {
    openFile = File.Open(filePath); // I'm making this up ... point is you are acquiring a resource that needs to be cleaned up after.

    fileProcessor(openFile); 
  }
  finally
  {
    openFile.Close(); // Or dispose, or whatever.
  }
}

Now, callers of this method don't have to worry about how to open the file or close / dispose of it. They can do something like this:

现在,此方法的调用者不必担心如何打开文件或关闭/处理它。他们可以这样做:

Helpers.ProcessFile("C://somefile.txt", f => 
 {
   while(var text = f.ReadLine())
   {
     Console.WriteLine(text);
   }
 });

回答by Sean

How about where you have related code that doesn't necessarily belong in a separate function of it's own right? Would this then be correct?

如果您有相关代码,而这些代码不一定属于它自己的单独功能,那又如何呢?那么这是正确的吗?

try
{
  // Part 1 Code Here

  try
  {
    // Part 2 Code Here
  }
  catch (Exception ex)
  {
    // Error from Part 2
  }
}
catch (Exception ex) 
{
  // Error from Part 1
} 

回答by Ahsen Amjad CASE UNiversity

try 
{
  ----
}
catch
{
   try
      {
           ---
      }
   catch
      {
        ---
      }
}

回答by Ronan Masangcay

//create a switch here and set it to 0 
try
{
    DoChunk1(); 
    //looks good. set the switch to 1
}
catch (Exception ex)
{
    // Log the exception here
}

// check the switch, if it is still zero at this point then you may halt your program here; else set the switch back to zero and execute your next try catch statement. totally agree with breaking them down as mentioned above

// 检查开关,如果此时它仍然为零,那么您可以在此处停止程序;否则将开关设置回零并执行下一个 try catch 语句。完全同意如上所述分解它们

try { DoChunk2(); //looks good. set the switch to 1 } catch (Exception ex) { // Log the exception here }

尝试 { DoChunk2(); //看起来挺好的。将开关设置为 1 } catch (Exception ex) { // 在此处记录异常 }