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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With