为什么我们必须关闭finally{}块下的对象
本文关键字:对象 finally 我们 为什么 | 更新日期: 2023-09-27 18:19:38
有人能解释为什么#1方法比#2更好吗?
1
try
{
}
catch
{
}
finally
{
reader.Close();
dataStream.Close();
response.Close();
}
2
try
{
reader.Close();
dataStream.Close();
response.Close();
}
catch
{
}
如果reader.Close()
引发异常,两个选项将永远不会关闭dataStream
或response
。
但是,在#2选项中,如果reader.Close()
之前的代码引发异常,则不会关闭任何对象。在#1中,您至少可以保证始终调用reader.Close()
,即使其他事情引发了异常。
不过,通常情况下,任何具有Close()
方法的对象都应该通过IDisposable.Dispose()
实现Close
,在这种情况下,我总是更喜欢使用using
而不是以下任一选项:
using(var reader = CreateReader())
{
using(var dataStream = CreateDataStream(reader))
{
using(var response = CreateResponse(dataStream))
{
// Use objects
}
}
}
这将强制所有对象正确关闭,但更干净。
我更喜欢方法3
using(var reader = ...)
using(var dataStream = ...)
using(var response = ...)
{
//...
}//all disposed (and implicitly closed) at the end of this scope
使用这个构造,编译器将转换为大致如下:
var reader = ...;
var dataStream = ...;
var response = ...;
try
{
//...
//even if an error happens here
}
finally
{
//this code still runs before control leaves this method.
reader.Close();
dataStream.Close();
response.Close();
}
由于Try块是为处理可能的失败而设计的,因此处理成功和不成功的情况都很重要。Try块中的项目可能会被调用,也可能不会被调用——这取决于失败是否发生以及在哪里发生。
通过将闭包语句放置到finally块中,可以确保无论Try部分是否成功,都将始终调用这些语句。这样,即使确实发生了故障,也不会留下读取器、数据流和响应。
如果在关闭所有对象之前,try块中的任何位置都发生异常,则不会关闭这些对象。finally块允许您在try块中引发异常时执行清理。
正如其他人所提到的,using
方法是我使用自己的代码的方式。编译器将using
转换为try{} finally{}
块。查看以下MSDN链接:http://msdn.microsoft.com/en-us/library/yh598w02.aspx
干杯。