Ort*_*und 132 .net c# garbage-collection memory-leaks memory-management
在我的类中,我实现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;
}
}
Run Code Online (Sandbox Code Playgroud)
在VS2012中,我的代码分析说要正确实现IDisposable,但我不确定我在这里做错了什么.
具体文字如下:
CA1063正确实现IDisposable在"用户"上提供Dispose(bool)的可覆盖实现,或将类型标记为已密封.对Dispose(false)的调用应该只清理本机资源.对Dispose(true)的调用应该清理托管和本机资源.stman User.cs 10
我已经阅读了这个页面,但是我担心我真的不明白这里需要做些什么.
如果任何人都可以用更多的术语来解释问题是什么和/或IDisposable应该如何实现,这将真的有帮助!
Dan*_*ann 104
这将是正确的实现,虽然我没有看到您需要在您发布的代码中处置任何内容.您只需要在以下时间实施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.
}
}
Run Code Online (Sandbox Code Playgroud)
D S*_*ley 55
首先,你不需要"清理" string
s和int
- 它们将由垃圾收集器自动处理.唯一需要清理的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;
}
}
Run Code Online (Sandbox Code Playgroud)
Cha*_*thJ 39
以下示例显示了实现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.
}
}
Run Code Online (Sandbox Code Playgroud)
Ser*_*rvy 14
IDisposable
存在以提供一种方法来清理垃圾收集器不会自动清理的非托管资源.
您正在"清理"的所有资源都是托管资源,因此您的Dispose
方法无需任何操作.你的班级根本不应该实施IDisposable
.垃圾收集器将自行处理所有这些字段.
Bel*_*gix 13
你需要像这样使用Disposable Pattern:
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);
}
Run Code Online (Sandbox Code Playgroud)
由于类没有获取任何非托管资源(文件,数据库连接等),因此您无需执行User
类.通常,我们将类标记为
至少具有一个字段或/和属性.在实施时,最好根据微软的典型方案:IDisposable
IDisposable
IDisposable
IDisposable
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);
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
104791 次 |
最近记录: |