Try-Finally Dispose和Using-statement的区别
本文关键字:区别 Using-statement Dispose Try-Finally | 更新日期: 2023-09-27 18:15:40
我一直在钻研微软的代码分析,并偶然发现了一些非常有趣的事情。net似乎使用了两种不同类型的Dispose,这取决于它被调用的方式。采用以下两个选项:
public void SqlConnectionUsing()
{
using (SqlConnection connection = new SqlConnection())
{
}
}
public void SqlConnectionFinally()
{
SqlConnection connection = new SqlConnection();
try
{
}
finally
{
connection.Dispose();
}
}
两个选项被翻译成完全相同的东西;在编译过程中。using变成了try-finally语句,在finally语句中调用了dispose方法。
我说a dispose method;因为哪种处置方法取决于您编写代码的方式。
当去using-statement
时,调用到callvirt instance void [mscorlib]System.IDisposable::Dispose()
(它是确切的il线)。
手动选择try-finally选项,dispose语句变为:callvirt instance void [System]System.ComponentModel.Component::Dispose()
.
为什么有一个不同的处置函数被调用?
如果需要,我可以添加整个il代码。
在编译过程中,using
语句转换为:
try
{
}
finally
{
((IDisposable)connection).Dispose();
}
实际上可以在同一个类中定义两个Dispose()
方法,一个显式地用于IDisposable
接口,还有一个类方法:
public class X : IDisposable
{
void IDisposable.Dispose() { }
public void Dispose() { }
}
但是,如果让这些方法有不同的行为,你真的会毁了别人的一天。此外,您可以在不实现IDisposable
的类中创建Dispose()
方法,但您将无法将其放置在using
语句中。
这是因为using
总是使用IDisposable.Dispose()
并从那里向上(所以它实际上是一个接口方法调用)。
实际上是:
using (IDisposable x = ...)
{ }
在最后,您实际上调用Component.Dispose()
方法,因为这是SqlConnection
的最高可用Dispose
方法。