The differences between Dispose method and Close method in C are discussed in detail

  • 2020-05-12 03:07:44
  • OfStack

Someone in the group asked how to empty the heap of string directly. It has been suggested to use the Dispose() method directly; Dispose() destroys objects and is a garbage collection mechanism. (using might be better here.)
When developing C# code, we often encounter a problem. Some class provide Close(), some class provide Dispose(), so what is the difference between Dispose and Close?

Here, specify the resources in the C# program (or.NET). In simple terms, each type in C# represents a resource, and resources fall into two categories:
Managed resources: resources allocated and released by CLR management, that is, objects from new in CLR;
Unmanaged resources: objects not managed by CLR, windows kernel objects, such as files, database connections, sockets, COM objects, etc. Without exception, if our type USES an unmanaged resource, or a managed resource that needs to be explicitly released, then we need to have the type inherit from the interface IDisposable. This is equivalent to telling the caller that the type needs to explicitly release the resource and that you need to call my Dispose method.

First of all, Dispose and Close should be basically 1. Close is designed for developers who are not familiar with Dispose. Because almost all developer know what Close does (especially developer with an C++ background).
But when we write code, if we want to implement Close and Dispose, we should pay attention to the design patterns of Close and Dispose. Some class of.net only provides Close, and is derived from IDisposable, and hides the Dispose method. Do you feel confused?

The key to these class is that they explicitly (explicitly) implement IDisposable. For an implicit implementation, you only need to call "newA().Dispose()", but for an explicit implementation, Dispose will not be a member of this class function. The only way to call 1 is if you need cast to IDisposable. (" new A().Dispose() "compiles, but" ((IDisposable)newA()).Dispose() "compiles.) So this meets the design requirements: provide Close(), hide Dispose(), and implement the IDisposable interface.

In the framework of.net, Close() is designed to be public, and call () is hidden inside Dispose(); Dispose() goes to call for another virtual Dispose(bool) function. So if you inherit from this class, you have to implement the Dispose(bool) method.

When you use call Close(), call will go to the Dispose(bool) method you overloaded to release the resource.
Here is a standard implementation that inherits the IDisposable interface type, which we call the Dispose pattern:


public class SampleClass : IDisposable
    {
        // Create a demonstration 1 Unmanaged resources 
        private IntPtr nativeResource = Marshal.AllocHGlobal(100);
        // Create a demonstration 1 Individual managed resources 
        private AnotherResource managedResource = new AnotherResource();
        private bool disposed = false;
        /// <summary>
        ///  implementation IDisposable In the Dispose methods 
        /// </summary>
        public void Dispose()
        {
            // Must be true
            Dispose(true);
            // Notifies the garbage collection mechanism that the finalizer (destructor) is no longer invoked 
            GC.SuppressFinalize(this);
        }
        /// <summary>
        ///  Not necessary, provided 1 a Close The method is simply to be more consistent with other languages (e.g C++ ) the specification of the 
        /// </summary>
        public void Close()
        {
            Dispose();
        }
        /// <summary>
        ///  Must, in case the programmer forgets to explicitly invoke it Dispose methods 
        /// </summary>
        ~SampleClass()
        {
            // Must be false
            Dispose(false);
        }
        /// <summary>
        ///  Non - sealed class modifier protected virtual
        ///  Seal class modifier private
        /// </summary>
        /// <param name="disposing"></param>
        protected virtual void Dispose(bool disposing)
        {
            if (disposed)
            {
                return;
            }
            if (disposing)
            {
                //  Clean up managed resources 
                if (managedResource != null)
                {
                    managedResource.Dispose();
                    managedResource = null;
                }
            }
            //  Clean up unmanaged resources 
            if (nativeResource != IntPtr.Zero)
            {
                Marshal.FreeHGlobal(nativeResource);
                nativeResource = IntPtr.Zero;
            }
            // Let the type know it has been released 
            disposed = true;
        }
        public void SamplePublicMethod()
        {
            if (disposed)
            {
                throw new ObjectDisposedException("SampleClass", "SampleClass is disposed");
            }
            // omit 
        }
    }


Related articles: