Search code examples
c#.netdisposeidisposable

Why do I need to create a property to check if a resource has been disposed when using disposable pastern in c#?


I need to be write a class where I want to enable the consumer to dispose the code by wrapping the code with using(...) statement in C#.

To do that, I must implement Microsoft's IDisposable interface.

Based on Microsoft approach on implementing it, I should do something like this

a generic interface that so

public interface ISomeClass : IDisposable
{
     // ... some methods to include
}

public class SomeClass : ISomeClass
{
     private readonly TimeTrackerContext _context;

    private bool disposed = false;

    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed && disposing && _context != null)
        {
            _context.Dispose();

        }
        this.disposed = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

I am trying to learn C# the correct way so I have some question regarding this implementation.

Question

Why do I really need to have a property that tell me if the object has been disposed or not before I dispose it?

In other words, Can't I just check if the _context is null instead before disposing it? Something like this

public class SomeClass : ISomeClass
{
    private readonly TimeTrackerContext _context;

    private void SelfDisposing()
    {
        if (_context != null)
        {
            _context.Dispose();
        }

    }

    public void Dispose()
    {
        SelfDisposing();
        GC.SuppressFinalize(this);
    }

    private void SelfDisposing(bool disposing)
    {
        if (_context != null && !this.disposed && disposing)
        {
            _context.Dispose();
        }

        this.disposed = true;
    }
}

Solution

  • _context won't be null if the object has already been disposed. It'll still reference the already disposed object.

    Now if you can determine whether or not your object is disposed without needing to store a boolean variable, then that's fine.

    What you shouldn't actually have is GC.SuppressFinalize Your object has no finalizer, so there is nothing to suppress.