5

I'm battling a bit to understand disposing of objects and garbage collection. In particular, I don't understand why I can still use a disposed object. I'm not trying to do anything practically, I'm just playing around with theory at the moment and in my understanding, I thought that I wouldn't be able to do the following:

class Program
{
    static void Main(string[] args)
    {
        Person p = new Person();
        using (p)
        {
            p.Name = "I am Name";
        }
        Console.WriteLine(p.Name); // I thought this would break because I've already disposed of p
        Console.ReadLine();
    }
}
public class Person : IDisposable
{
    public string Name;
    public void Dispose()
    {
        Console.WriteLine("I got killed...");
    }
}

I'm hoping that someone could perhaps give me some direction or guidance here so as to clear up my misunderstanding of this concept?

macmatthew
  • 302
  • 2
  • 9
  • 1
    The conventional way to use `using` is `(using p = new Person()){ ... }` . This way you don't have to worry about the disposable once you're done with it. – shay__ Mar 06 '16 at 09:43
  • 1
    @shay__: Yes you do - because often there are wrapper classes which will also dispose what they wrap, e.g. with streams and `StreamWriter`. Also, there can be times where you *do* want to access the disposed object afterwards. I think it's a perfectly reasonable question. – Jon Skeet Mar 06 '16 at 09:47
  • @JonSkeet Thank you very much! I think that clears up my misunderstanding here. I kept thinking the object gets destroyed by Dispose() but it's just my opportunity to get rid of unmanaged resources that the CLR wouldn't get rid of for me and then I can do what I want with the managed stuff after that until no longer needed at which time the GC would then sort that out for me? I was thinking that there was some magical stuff that the Dispose() method did which was baffling me with the things I was trying. Thanks again! – macmatthew Mar 06 '16 at 09:59

3 Answers3

11

Disposing of an object doesn't do anything magical - the CLR doesn't really care about IDisposable at all... it's just a framework interface that has support within C# (and other languages). Calling Dispose is just like calling other methods.

If you don't make a disposed object fail when you perform further operations on it, it won't. Indeed, there are some cases where you really want to be able to - for example, calling ToArray on MemoryStream is fine after it's disposed, even though you can't call Read etc. That can be really handy in situations where the writes to a MemoryStream are chained from a wrapper which will dispose of the MemoryStream, but you want the data afterwards.

In general though, you should code as if you can't use a disposed object after disposal, unless you know for sure that it still supports the operations you need. A default position of "I expect it will break..." is a safe one.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 2
    Note that .Net provides the [ObjectDisposedException](https://msdn.microsoft.com/en-us/library/system.objectdisposedexception%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396) class that you can throw if something calls a method in your class after it's been disposed. Some disposable classes do track if they've been disposed, and throw `ObjectDisposedException` if you try to use them afterwards - but other disposable classes do not. – Matthew Watson Mar 06 '16 at 10:14
4

Dispose pattern is used when you have an object that uses unmanaged resources that needs to be freed when no longer needed. Managed resources are freed automatically by GC.

In your example, the string Name is a managed resource. If you had an opened file there, that would be an unmanaged resource. Dispose method would then care about closing the file handle, which would make the object's file access not usable after the Dispose. Yet still, you could ask for the Name, because until GC collects that object, it will exist.

Recommended reading: MSDN Dispose Pattern

Wapac
  • 4,058
  • 2
  • 20
  • 33
1

IDisposable is convention to handle Unmanaged resource inside managed code.

You are implementing IDisposable interface, and later you are just doing Dispose() method call, not destructing or killing actual object

What is unmanaged resource ?

Unmanaged resource is resource which Garbage collector can not collect. for example memory that are allocated by other program or code outside managed code. So GC can not manage automaticly.

Davit Tvildiani
  • 1,915
  • 3
  • 19
  • 29