Search code examples
c#asp.netgarbage-collectionidisposablesuppressfinalize

Why can we still use a disposed object?


I have DisposedPatterenDemo class inherit from IDisposable. I have Disposed the object of this class and then after it tries to call the Method() of the same class, I am getting returned value from Method but obj is already disposed of. var res=obj.Method(); not failing ? Why it is not getting failed?

     class Program
        {
            static void Main(string[] args)
            {

                DisposedPatterenDemo obj = new DisposedPatterenDemo();
                obj.Initialize();
                obj.Dispose();
                var res=obj.Method(); //Here it return value
    }
    }


 class DisposedPatterenDemo:IDisposable
    {
        private bool Disposed = false;
        StreamReader str = null;
        PaymentStub obj = new PaymentStub();

        public void Initialize()
        {
            str = new StreamReader(@"C:\Test\abc.pdf");
        }
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);

        }
        public string Method()
        {
            var abc = "New";
            return abc;
        }
        public void Dispose(bool disposing)
        {
            if (!Disposed)
            {
                if (disposing)
                {
                    Console.WriteLine("Called From Dispose");
                    if(str!=null)
                    {
                        str.Dispose();
                    }
                }
                else
                {
                    //Clear all the unmanaged resources here  
                }
                Disposed = true;
            }
        }
    }

Solution

  • Disposing only means that Unmanaged resources used by the object would be disposed off. It does not mean that the object would be cleared off memory. This means that methods of that object, which does not depend on any unamanaged resources could still be called without problem.

    To prevent this, As @Matthew suggested, you need to keep an instance variable that tells whether the current instance was disposed or not, and handle it accordingly in the method.