我一直在深入研究微软的Code Analysis,偶然发现了一些非常有趣的东西。 .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-method。
我说 a dispose-method;因为什么样的dispose方法取决于你编写代码的方式。
当前往using-statement
时,呼叫转到callvirt instance void [mscorlib]System.IDisposable::Dispose()
(这是确切的IL线)。
并手动执行try-finally选项,dispose语句更改为:callvirt instance void [System]System.ComponentModel.Component::Dispose()
。
为什么调用dispose函数会有区别?
如果需要,我可以添加整个IL代码。
答案 0 :(得分:4)
在编译期间,using
语句转换为:
try
{
}
finally
{
((IDisposable)connection).Dispose();
}
您实际上可以在同一个类中定义两个Dispose()
方法,一个显式用于IDisposable
接口,以及一个类方法:
public class X : IDisposable
{
void IDisposable.Dispose() { }
public void Dispose() { }
}
但是,你可以通过让这些方法有不同的行为来破坏某人的某一天。
此外,您可以在未实现Dispose()
的类中创建IDisposable
方法,但您无法将其置于using
语句中。< / p>
答案 1 :(得分:0)
这是因为using
总是使用IDisposable.Dispose()
并从那里向上移动(所以它实际上是一个接口方法调用)。
实际上是:
using (IDisposable x = ...)
{ }
最后,您实际上是在调用Component.Dispose()
方法,因为这是Dispose
的最高可用SqlConnection
方法。