Try-Finally Dispose和Using-statement之间的区别

时间:2014-07-30 10:21:52

标签: c# .net dispose

我一直在深入研究微软的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代码。

2 个答案:

答案 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方法。