Using Statement VS. Idisposable.Dispose()

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:

  1. using creates a new scope.

  2. 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 a try/finally construct that places "if not null then .Dispose()" in the finally 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 a using?

No, it will break due to access to the disposed object.



Should I call Close() before exiting the using 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 as Dispose is called. Within the using 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



Leave a reply



Submit