简单的最佳实践问题。
你应该嵌套try catch语句还是只使用方法。
例如,如果你有一个打开文件的方法可以工作并关闭文件,那么你可以在try catch之外打开和关闭,或者更确切地说是finally块中的close。
现在如果你的open方法失败了,那么该方法会断言吗?那么你应该将它包装在try catch块中,还是应该从另一个方法中调用,而另一个方法又作为try catch块调用?
答案 0 :(得分:15)
在打开文件的方法的上下文中,我将使用using语句与try catch。 using语句确保在发生异常时调用Dispose。
using (FileStream fs = new FileStream(file, FileMode.Open))
{
//do stuff
}
做同样的事情:
FileStream fs;
try
{
fs = new FileStream(file, FileMode.Open);
//do Stuff
}
finally
{
if(fs!=null)
fs.Dispose();
}
答案 1 :(得分:11)
既然我们有lambdas和类型推断以及其他一些东西,那么在其他语言中有一个常见的习惯用法现在在C#中很有意义。您的示例是关于打开文件,对其执行某些操作,然后关闭它。那么,现在,你可以创建一个打开文件的辅助方法,并且还要确保关闭/处理/清理,但是调用你为“do stuff”部分提供的lambda。这将帮助您在一个地方获得复杂的try / catch / finally dispose / cleanup,然后一遍又一遍地使用它。
以下是一个例子:
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.
}
}
现在,此方法的调用者不必担心如何打开文件或关闭/处置它。他们可以这样做:
Helpers.ProcessFile("C://somefile.txt", f =>
{
while(var text = f.ReadLine())
{
Console.WriteLine(text);
}
});
答案 2 :(得分:7)
这是一个样式问题,但对我来说,我尝试在单个方法中永远不会有多个try / catch / finally嵌套级别。在您进行嵌套尝试时,您几乎肯定违反了1 function = 1操作主体,并且应该使用第二种方法。
答案 3 :(得分:4)
取决于你想要做什么,但在大多数情况下,嵌套的try / catches是一个过于复杂的函数的标志(或者是一个不太了解异常如何工作的程序员!)。
在打开文件的情况下,我会使用IDisposable holder和using子句,因此不需要任何明确的try / catch。
答案 4 :(得分:3)
你有哪些相关代码并不一定属于它自己的独立功能怎么样?这会是正确的吗?
try
{
// Part 1 Code Here
try
{
// Part 2 Code Here
}
catch (Exception ex)
{
// Error from Part 2
}
}
catch (Exception ex)
{
// Error from Part 1
}
答案 5 :(得分:1)
大多数时候我会将嵌套的try / catch块分解为函数。但我有时编写代码来捕获并记录我的应用程序抛出的所有未捕获的异常。但是如果日志代码失败怎么办?所以我还有另一个尝试/捕获,只是为了防止用户看到默认的.NET未处理的异常对话框。但即使是这些代码也很容易被重构为函数而不是嵌套的try / catch块。
try
{
try
{
DoEverything();
}
catch (Exception ex)
{
// Log the exception here
}
}
catch (Exception ex)
{
// Wow, even the log is broken ...
}
答案 6 :(得分:0)
//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
}
//检查开关,如果此时它仍然为零,那么你可以在这里停止你的程序; else将开关设置回零并执行下一个try catch语句。完全同意如上所述将其分解
试 { DoChunk2(); //看起来不错。将开关设置为1 } catch(Exception ex) { //在此处记录异常 }
答案 7 :(得分:-2)
try
{
----
}
catch
{
try
{
---
}
catch
{
---
}
}