Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between Try-Finally Dispose and Using-statement

Tags:

c#

.net

dispose

I have been diving into Code Analysis of Microsoft and stumbled upon something quite interesting. .NET seems to use two different types of Dispose, depending on the way it is called. Take the following two options:

public void SqlConnectionUsing()
{
    using (SqlConnection connection = new SqlConnection())
    {
    }
}

public void SqlConnectionFinally()
{
    SqlConnection connection = new SqlConnection();
    try
    {
    }
    finally
    {
        connection.Dispose();
    }
}

Both options get translated to exactly the same thing; during compilation. The using becomes a try-finally statement with inside the finally statement a call to a Dispose-method.

I say a dispose-method; because what kind of dispose-method depends on the way you have written your code.

When going for the using-statement, a call goes to callvirt instance void [mscorlib]System.IDisposable::Dispose() (it is the exact IL-line).

And manually taking the try-finally option, the dispose-statement changes to: callvirt instance void [System]System.ComponentModel.Component::Dispose().

Why is there a difference in what dispose function gets called?

I can add the entire IL-code if required.

like image 826
Matthijs Avatar asked Sep 30 '22 05:09

Matthijs


1 Answers

During compilation, the using statement translates to:

try
{
}
finally
{
    ((IDisposable)connection).Dispose();
}

You can actually define two Dispose() methods inside the same class, one explicitly for the IDisposable interface, and a class method:

public class X : IDisposable
{
    void IDisposable.Dispose() { } 
    public void Dispose() { }
}

You could really ruin someone's day by letting these methods have different behavior, though.

Furthermore, you can create a Dispose() method in a class that does not implement IDisposable, but you won't be able to place it in a using statement.

like image 113
C.Evenhuis Avatar answered Oct 12 '22 05:10

C.Evenhuis