Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can you still use a disposed object?

Tags:

c#

oop

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?

like image 786
macmatthew Avatar asked Mar 06 '16 09:03

macmatthew


People also ask

Why do we use Dispose?

Dispose improves performance and optimizes memory by releasing unmanageable objects and scarce resources, like Graphics Device Interface (GDI) handles used in applications with restricted Windows space. The Dispose method, provided by the IDisposable interface, implements Dispose calls.

What does Cannot access a disposed object mean?

: 'Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application.

What happens if Dispose is not called?

Implement a finalizer to free resources when Dispose is not called. By default, the garbage collector automatically calls an object's finalizer before reclaiming its memory. However, if the Dispose method has been called, it is typically unnecessary for the garbage collector to call the disposed object's finalizer.

Why do we need Dispose in C#?

The dispose pattern is used for objects that implement the IDisposable interface, and is common when interacting with file and pipe handles, registry handles, wait handles, or pointers to blocks of unmanaged memory. This is because the garbage collector is unable to reclaim unmanaged objects.


2 Answers

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.

like image 64
Jon Skeet Avatar answered Nov 13 '22 16:11

Jon Skeet


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

like image 34
Wapac Avatar answered Nov 13 '22 16:11

Wapac