正确实施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在“用户”上提供Dispose(bool)的可覆盖实现,或将该types标记为密封。 调用Dispose(false)应该只清理本地资源。 调用Dispose(true)应该清理托pipe资源和本地资源。 stman User.cs 10

供参考: CA1063:正确实施IDisposable

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

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

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

  1. 你有非托pipe资源
  2. 你坚持引用本身是一次性的东西。

您发布的代码中没有任何内容需要处理。

 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 ,它们将被垃圾收集器自动处理。 Dispose中唯一需要清理的是非托pipe资源或实现IDisposable托pipe资源。

但是,假设这只是一个学习练习, 推荐使用 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接口的一般最佳实践。 参考

请记住,只有在您的类中有非托pipe资源时,才需要析构函数(终结器)。 如果你添加一个析构函数,你应该在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. } } 

IDisposable存在为您提供一种方法来清理垃圾收集器不会自动清理的非托pipe资源。

您“清理”的所有资源都是托pipe资源,因此您的Dispose方法完成任何操作。 你的课不应该实现IDisposable 。 垃圾收集者将自行处理所有这些领域。

你需要像这样使用一次性模式

 private bool _disposed = false; protected virtual void Dispose(bool disposing) { if (!_disposed) { if (disposing) { // Dispose any managed objects // ... } // Now disposed of any unmanaged objects // ... _disposed = true; } } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } // Destructor ~YourClassName() { Dispose(false); } 

您不需要将您的User类设置为IDisposable,因为该类不会获取任何非pipe理资源(文件,数据库连接等)。 通常,如果类至less有一个IDisposable字段或/和属性,则将其标记为IDisposable。 在实现IDisposable的时候,最好按照微软的典型scheme:

 public class User: IDisposable { ... protected virtual void Dispose(Boolean disposing) { if (disposing) { // There's no need to set zero empty values to fields // id = 0; // name = String.Empty; // pass = String.Empty; //TODO: free your true resources here (usually IDisposable fields) } } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } } 

无论何时您想要一个确定性的(确认的)垃圾收集,都可以使用Idisposable。

 class Users : IDisposable { ~Users() { Dispose(false); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); // This method will remove current object from garbage collector's queue // and stop calling finilize method twice } public void Dispose(bool disposer) { if (disposer) { // dispose the managed objects } // dispose the unmanaged objects } } 

创build和使用Users类时,使用“using”块来避免显式调用dispose方法:

 using (Users _user = new Users()) { // do user related work } 

使用块创build的Users对象的末端将通过隐式调用dispose方法进行处理。