Using statement vs. IDisposable.Dispose()
using
is basically the equivalent of:
try
{
// code
}
finally
{
obj.Dispose();
}
So it also has the benefit of calling Dispose()
even if an unhandled exception is thrown in the code within the block.
Difference between using and .Dispose() call in C#
They differ in a couple of ways:
using
creates a new scope.using
calls.Dispose()
regardless of how control leaves the block (if the object is not null at that point). It would be the same as writing atry
/finally
construct that places "if not null then.Dispose()
" in thefinally
block, but in a format that expresses the intent.
It exists so that if control leaves the block in any way (an exception occurs or a return
or break
is encountered), the .Dispose()
is still called. It is also more expressive because it better indicates the programmer's intent for this case than a generic try
/finally
construct.
Which is better, and when: using statement or calling Dispose() on an IDisposable in C#?
The first is better. It ensures it is disposed even if an exception is thrown, and it correctly handles the case where Create(0)
returns null (i.e. it doesn't attempt to call Dispose()
on a null instance).
Occasions when the using statement and IDisposable should never be used
I would say, always use using
unless the documentation tells you not to (as in your example).
Having a Dispose
method throw exceptions rather defeats the point of using it (pun intended). Whenever I implement it, I always try to ensure that no exceptions will be thrown out of it regardless of what state the object is in.
PS: Here's a simple utility method to compensate for WCF's behaviour. This ensures that Abort
is called in every execution path other than when Close
is called, and that errors are propogated up to the caller.
public static void CallSafely<T>(ChannelFactory<T> factory, Action<T> action) where T : class {
var client = (IClientChannel) factory.CreateChannel();
bool success = false;
try {
action((T) client);
client.Close();
success = true;
} finally {
if(!success) {
client.Abort();
}
}
}
If you find any other funny behaviour cases elsewhere in the framework, you can come up with a similar strategy for handling them.
C# Using Statement and iDisposable
You could ...
- Look for the presence of a
Dispose
member - Look at the definition of your type (F12)
- Do as you suggest, wrap in a using and see what the compiler says
Although, the best thing is to learn what IDisposable is used for, soon you will understand the types that do and should implement this interface. i.e. external resources, unmanaged type wrappers (GDI graphics objects for example), limited resources (database connections)
What is the relationship between the using keyword and the IDisposable interface?
If you use the using
statement the enclosed type must already implement IDisposable
otherwise the compiler will issue an error. So consider IDisposable implementation to be a prerequisite of using.
If you want to use the using
statement on your custom class, then you must implement IDisposable
for it. However this is kind of backward to do because there's no sense to do so for the sake of it. Only if you have something to dispose of like an unmanaged resource should you implement it.
// To implement it in C#:
class MyClass : IDisposable {
// other members in you class
public void Dispose() {
// in its simplest form, but see MSDN documentation linked above
}
}
This enables you to:
using (MyClass mc = new MyClass()) {
// do some stuff with the instance...
mc.DoThis(); //all fake method calls for example
mc.DoThat();
} // Here the .Dispose method will be automatically called.
Effectively that's the same as writing:
MyClass mc = new MyClass();
try {
// do some stuff with the instance...
mc.DoThis(); //all fake method calls for example
mc.DoThat();
}
finally { // always runs
mc.Dispose(); // Manual call.
}
Difference between Try-Finally Dispose and Using-statement
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.
Is Close() same as Using statement
Is Close() same as Using statement?
No it is not.
Should you call
Close()
after ausing
?
No, it will break due to access to the disposed object.
Should I call
Close()
before exiting theusing
block?
It's complicated. If the IDisposable
interface is implemented correctly: no. Otherwise: possibly.
Close()
has no relation to IDisposable
interface, see: https://msdn.microsoft.com/en-us/library/system.idisposable(v=vs.110).aspx
using
only applies to IDisposable
inherited objects, see: https://msdn.microsoft.com/en-us/library/yh598w02.aspx
Thus:Close()
and Dispose()
may not considered to be related in any way.
When the IDisposable
interface is correctly implemented, you may assume all clean-up necessary will be carried out. This implies an internal call to a Close()
method would be carried out. This means that an explicit call to Close()
should not be necessary.
The other way round; when a object is of type IDisposable
and exposes a Close()
method, a call to Close()
will not be sufficient to properly dispose/clean-up the object. Dispose()
must still be called, you can do this directly, or through the using
statement.
You can also let the garbage-collector handle the Dispose()
call for you (if its correctly implemented, see: Proper use of the IDisposable interface) But this is considered bad-practice, since you need to rely on a proper implementation and have no direct control over the GC timing.
Please note, a reason to implement a Close()
function, is usually to give a developer a way to reuse the object. After calling Dispose()
the object is considered to be marked for finalization and may not be used any more.
Does using statement keep a reference to object(s) it receive?
To answer the documentation and reference portion of your question:
The documentation for the using
statement notes:
The using statement calls the
Dispose
method on the object in the correct way, and (when you use it as shown earlier) it also causes the object itself to go out of scope as soon asDispose
is called. Within theusing
block, the object is read-only and cannot be modified or reassigned.
As far as the syntax of the first code block goes, the C# standard has the following for the syntax:
using_statement
: 'using' '(' resource_acquisition ')' embedded_statement
;
resource_acquisition
: local_variable_declaration
| expression
;
There, you'll note that resource_acquisition
can be a local variable declaration, or an expression, which is what your first code block uses.
Does using statement always dispose the object?
Yes, that's the whole point. It compiles down to:
SomeDisposableType obj = new SomeDisposableType();
try
{
// use obj
}
finally
{
if (obj != null)
((IDisposable)obj).Dispose();
}
Be careful about your terminology here; the object itself is not deallocated. The Dispose()
method is called and, typically, unmanaged resources are released.
Related Topics
Get Image Orientation and Rotate as Per Orientation
Scope of Static Variable in Multi-User ASP.NET Web Application
Why Is Application.Restart() Not Reliable
How to Return Anonymous Type from C# Method That Uses Linq to SQL
How to Sort an Observable Collection
One to One Optional Relationship Using Entity Framework Fluent API
Creating an Instance Using Ninject with Additional Parameters in the Constructor
C# Sending Mails with Images Inline Using Smtpclient
How to Copy Part of an Array to Another Array in C#
C# Open File with Default Application and Parameters
Is It Necessary to Manually Close and Dispose of SQLdatareader
Deleting Specific Rows from Datatable
Custom App.Config Section with a Simple List of "Add" Elements