Embedd_0913
Embedd_0913

Reputation: 16555

What is the difference between Dispose and setting reference to null in C#?

I have two code samples and I want to know what is the deifference between them and which is better to use as best practice and performance wise:

using (TestForm test = new TestForm())
{
test.ShowDialog();
}

and the other is:

TestForm test = null; 
try
{
test = new TestForm();
 test.ShowDialog();
}
catch(Exception ex)
{
}
finally
{
test = null; 
}

Upvotes: 2

Views: 1598

Answers (3)

InBetween
InBetween

Reputation: 32760

The IDisposable pattern is a mechanism to timely free unmanaged and managed resources that an object may be consuming.

The typical way the pattern is implemented is as follows:

public void Dispose() //Implementes the IDisposable interface
{ 
    this.Dispose(true);
    GC.SupressFinalize(this); //All resources have been released, no need to run the finalizer. We make the GC's life a little easier;
} 

protected void Dispose(bool disposing)
{
     if (disposing)
     {
        //Relesase managed resources.
     }

    //Release unmanaged resources.
}

~MyDisposableObject()  //finalizer
{
    this.Dispose(false)
}

The thing to note here is that the release of resources through the Dispose method is very similar to what you logically would expect to find in a finalizer. It is not done directly in the finalizer due to two main reasons:

  1. the finalizer is not executed in a deterministic order. That is why we do not dispose managed resources from the finalizer (Dispose(false)), as some or all the managed resources held by the object might have been finalized before the object itself. This is not true with unmanaged resources as, by definition, they will never be finalized by the GC.

  2. We do not know when the finalizer is run (it is up to the GC).

The basic idea is that an object implementing IDisposable is a sign for any consumer saying: "hey, I'm holding on to a certain amount of unmanaged and/or managed resources that will eventually be released when the GC decides I'm no longer useful, but if you need those resources back in a timely way, call Dispose() and I'll be happy to oblige.".

On the other hand, setting a reference variable to null is not freeing any resources at all. If the reference you have removed from the object was the only one to said object, then the object will eventually be collected by the GC and managed and unmanaged resources will be freed (when, is anyones guess).

If there were more live references still pointing to the object, then the object would live one and no resources whatsoever would be freed.

Upvotes: -1

Joey
Joey

Reputation: 354576

Dispose() is for freeing unmanaged resources. This may be done in a finalizer as well (which might call Dispose()) but don't rely on it. If it isn't done, then you leak unmanaged resources.

Setting a reference to null only means that a particular reference no longer points to that object. It can live on quite a while after that (or even indefinitely if you have another reference – well, if you have multiple reference to an object you Dispose()d of, then it gets ugly, probably).

Generally, always call Dispose() on IDiposables when you're done with them. It's easier if you wrap them into a using statement:

using (var foo = new SomeDiposableObject()) {
  // do something with foo
}

Upvotes: 4

Matteo Mosca
Matteo Mosca

Reputation: 7448

The IDisposable interface defines the Dispose method, as well as the possibility to use the "using" syntax. The dispose method of a class can be implemented to release resources, close database connections and any sort of finalizing and cleanup. Just setting the class instance to null won't execute any of the code defined in the dispose method. As a generic rule, if a class implements IDisposable, dispose should be called when you're finished with the class instance.

Upvotes: 7

Related Questions