正确实施IDisposable

在我的课程中,我实现了IDisposable,如下所示:

public class User : IDisposable
{
    public int id { get; protected set; }
    public string name { get; protected set; }
    public string pass { get; protected set; }

    public User(int UserID)
    {
        id = UserID;
    }
    public User(string Username, string Password)
    {
        name = Username;
        pass = Password;
    }

    // Other functions go here...

    public void Dispose()
    {
        // Clear all property values that maybe have been set
        // when the class was instantiated
        id = 0;
        name = String.Empty;
        pass = String.Empty;
    }
}

在VS2012中,我的代码分析说要正确实现IDisposable,但我不确定我在这里做了什么错误。
确切的文字如下:

CA1063正确实现IDisposable在'User'上提供Dispose(bool)的可覆盖实现,或将该类型标记为密封。 调用Dispose(false)应该只清理本地资源。 调用Dispose(true)应该清理托管资源和本地资源。 stman User.cs 10

供参考:CA1063:正确实施IDisposable

我已经读完了这个页面,但是我恐怕我不太明白这里需要做什么。

如果任何人都可以更清楚地解释问题是什么和/或如何实施IDisposable,那真的会有帮助!


这将是正确的实现,虽然我没有看到任何你需要在你发布的代码中处理的东西。 您只需在以下情况下实施IDisposable

  • 你有非托管资源
  • 你坚持引用本身就是一次性的东西。
  • 您发布的代码中没有任何内容需要处理。

    public class User : IDisposable
    {
        public int id { get; protected set; }
        public string name { get; protected set; }
        public string pass { get; protected set; }
    
        public User(int userID)
        {
            id = userID;
        }
        public User(string Username, string Password)
        {
            name = Username;
            pass = Password;
        }
    
        // Other functions go here...
    
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    
        protected virtual void Dispose(bool disposing)
        {
            if (disposing) 
            {
                // free managed resources
            }
            // free native resources if there are any.
        }
    
    }
    

    首先,您不需要“清理” stringint s - 它们将由垃圾收集器自动处理。 Dispose中唯一需要清理的是非托管资源或实现IDisposable托管资源。

    但是,假设这只是一个学习练习,推荐使用IDisposable是添加一个“安全捕获”来确保任何资源不会被处理两次:

    public void Dispose()
    {
        Dispose(true);
    
        // Use SupressFinalize in case a subclass 
        // of this type implements a finalizer.
        GC.SuppressFinalize(this);   
    }
    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing) 
            {
                // Clear all property values that maybe have been set
                // when the class was instantiated
                id = 0;
                name = String.Empty;
                pass = String.Empty;
            }
    
            // Indicate that the instance has been disposed.
            _disposed = true;   
        }
    }
    

    以下示例显示了实现IDisposable接口的一般最佳实践。 参考

    请记住,只有在您的类中有非托管资源时,您才需要析构函数(终结器)。 如果你添加一个析构函数,你应该在Dispose中压缩Finalization ,否则它将导致你的对象驻留在内存中两个垃圾周期(注意:读取Finalization的工作原理)。 以上例子详细阐述。

    public class DisposeExample
    {
        // A base class that implements IDisposable. 
        // By implementing IDisposable, you are announcing that 
        // instances of this type allocate scarce resources. 
        public class MyResource: IDisposable
        {
            // Pointer to an external unmanaged resource. 
            private IntPtr handle;
            // Other managed resource this class uses. 
            private Component component = new Component();
            // Track whether Dispose has been called. 
            private bool disposed = false;
    
            // The class constructor. 
            public MyResource(IntPtr handle)
            {
                this.handle = handle;
            }
    
            // Implement IDisposable. 
            // Do not make this method virtual. 
            // A derived class should not be able to override this method. 
            public void Dispose()
            {
                Dispose(true);
                // This object will be cleaned up by the Dispose method. 
                // Therefore, you should call GC.SupressFinalize to 
                // take this object off the finalization queue 
                // and prevent finalization code for this object 
                // from executing a second time.
                GC.SuppressFinalize(this);
            }
    
            // Dispose(bool disposing) executes in two distinct scenarios. 
            // If disposing equals true, the method has been called directly 
            // or indirectly by a user's code. Managed and unmanaged resources 
            // can be disposed. 
            // If disposing equals false, the method has been called by the 
            // runtime from inside the finalizer and you should not reference 
            // other objects. Only unmanaged resources can be disposed. 
            protected virtual void Dispose(bool disposing)
            {
                // Check to see if Dispose has already been called. 
                if(!this.disposed)
                {
                    // If disposing equals true, dispose all managed 
                    // and unmanaged resources. 
                    if(disposing)
                    {
                        // Dispose managed resources.
                        component.Dispose();
                    }
    
                    // Call the appropriate methods to clean up 
                    // unmanaged resources here. 
                    // If disposing is false, 
                    // only the following code is executed.
                    CloseHandle(handle);
                    handle = IntPtr.Zero;
    
                    // Note disposing has been done.
                    disposed = true;
    
                }
            }
    
            // Use interop to call the method necessary 
            // to clean up the unmanaged resource.
            [System.Runtime.InteropServices.DllImport("Kernel32")]
            private extern static Boolean CloseHandle(IntPtr handle);
    
            // Use C# destructor syntax for finalization code. 
            // This destructor will run only if the Dispose method 
            // does not get called. 
            // It gives your base class the opportunity to finalize. 
            // Do not provide destructors in types derived from this class.
            ~MyResource()
            {
                // Do not re-create Dispose clean-up code here. 
                // Calling Dispose(false) is optimal in terms of 
                // readability and maintainability.
                Dispose(false);
            }
        }
        public static void Main()
        {
            // Insert code here to create 
            // and use the MyResource object.
        }
    }
    
    链接地址: http://www.djcxy.com/p/54493.html

    上一篇: Implementing IDisposable correctly

    下一篇: Correct use of IDisposable pattern when using Managed C++ wrapper in C#