The short answer is yes most definitely. You need to call dispose on any object that is disposable. This is used to clean up unmanaged resources and dependencies.
Also NOTE: The garbage collector does not call Dispose on or look for IDisposable types.
If it is disposable within the method then it is ideal to use a using
statement like so.
public void Start()
{
for (int i = 0; i < 5; i++)
{
using (var foo = new DisposableFoo())
using (var bar = new DisposableBar())
{
foo.SomeFunc = x => bar.DoSomethingWithX(x);
_foos.Add(foo);
}
}
}
If the variable is class level then your class should also implement IDisposable and dispose of the disposable objects it uses within it as well.
Here is a good link where I give more detail about disposing objects.
Another thing to keep in mind is that sometimes (in languages like C#) we can have circular dependencies (which is bad practice.) However; it happens a lot. If your object is garbage collected and there is a circular dependency it hangs around until the other object is also garbage collected and it causes the process to be ugly. It's all behind the scenes and usually isn't a big deal for most apps but being aware of this is important. Although you should not have circular dependencies you can implement IDisposable to clean up dependencies before going to the garbage collector, making this process cleaner. (Just remember having them is bad to start with... That said, Entity Framework is built on circular dependencies so go figure.)
Another NOTE: It is not uncommon to see the Dispose method added also to the destructor of an object; especially if the object is lower level, singleton, or static, to insure the disposable types are taken care of during garbage collection. This would look something like:
public class SomeClass : IDisposable
{
//pretend we implement a singleton pattern here
//pretend we implement IDisposable here
~SomeClass()
{
Dispose();
}
}
UPDATE:
To update the answer based on your clarification I believe you're asking what happens to the variable you retrieve from a disposable object, after that disposable object is disposed. This is tricky behavior and should be thought out well when developing a disposable type. Here's some code that shows the results of similar situation that might help you understand.
Also. whose responsible for this should be decided when developing the type but in most cases any information you give to the client should be left good for the client even after you're disposed. In other words, it would be best practice to NOT remove or dispose or manipulate any information you allow the user of your type to retrieve when you are disposing.
using System;
using System.Collections.Generic;
namespace Disposable_Variables_Reference
{
class Program
{
static void Main(string[] args)
{
List<string> DCNames = null;
string DCName = string.Empty;
int DCValue;
using (var disposableClass = new DisposableClass())
{
DCNames = disposableClass.Names;
DCName = disposableClass.Name;
DCValue = disposableClass.Value;
foreach (var name in DCNames) Console.WriteLine(name);
Console.WriteLine(DCName);
Console.WriteLine(DCValue);
}
foreach (var name in DCNames) Console.WriteLine(name);
Console.WriteLine(DCName);
Console.WriteLine(DCValue);
Console.Read();
}
public class DisposableClass : IDisposable
{
public List<string> Names { get; set; } = new List<string>() { "Michael", "Mark", "Luke", "John" };
public string Name { get; set; } = "Gabriel";
public int Value { get; set; } = 20;
public void Dispose()
{
Names.Clear();
Name = string.Empty;
Value = 0;
}
}
}
}
Output:
Michael
Mark
Luke
John
Gabriel
20
Gabriel
20
Names is a List (reference type) and IS NOT re-written to the output.
Name is string (immutable reference type) and IS re-written to the output.
Value is int (value type) and IS re-written to the output.
However; if you reassign Names
in the Dispose()
method, instead of clearing it, then it WILL ALSO be re-written. Example including just the dispose method change.
public void Dispose()
{
Names = null; //notice here we re-assign Names to null.
Name = string.Empty;
Value = 0;
}
New Output:
Michael
Mark
Luke
John
Gabriel
20
Michael
Mark
Luke
John
Gabriel
20
Knowing this the proper way to expose Names
would be to leave it alone in the Dispose()
method or expose name like so; returning a new list, so that any referendes to it are not removed when disposing.
private List<string> names = new List<string>() { "Michael", "Mark", "Luke", "John" };
public List<string> Names
{
get { return names.ToList() ; }
set { names = value; }
}
Of course this entire answer is for logic and clarification. There is no reason to use IDisposable in the DisposableClass
example I've given.