在我的课程中,我按如下方式实现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)的可覆盖实现,或将类型标记为已密封。对Dispose(false)的调用应该只清理本机资源。对Dispose(true)的调用应该清理托管和本机资源。 stman User.cs 10
供参考:CA1063: Implement IDisposable correctly
我已经阅读了这个页面,但我担心我真的不明白这里需要做些什么。
如果有人能用更多的术语解释问题是什么和/或IDisposable应该如何实施,那将真的有用!
答案 0 :(得分:95)
这将是正确的实现,虽然我没有看到您需要在您发布的代码中处置任何内容。您只需在以下时间实施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.
}
}
答案 1 :(得分:53)
首先,您不需要“清理”string
和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;
}
}
答案 2 :(得分:37)
以下示例显示了实现<rule name="Redirect to HTTPS" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTPS}" pattern="^OFF$" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}" redirectType="SeeOther" />
</rule>
接口的一般最佳做法。 Reference
请记住,只有在类中有非托管资源时才需要析构函数(终结器)。如果添加析构函数,则应该在Dispose 中禁止Finalization,否则会导致对象驻留在内存中两个垃圾循环(注意:Read how Finalization works)。下面的例子详细阐述了上述内容。
IDisposable
答案 3 :(得分:13)
IDisposable
的存在是为了清理垃圾收集器不会自动清理的非托管资源。
您正在“清理”的所有资源都是托管资源,因此您的Dispose
方法无法完成任何操作。您的班级不应该实施IDisposable
。垃圾收集器将自行处理所有这些字段。
答案 4 :(得分:12)
你需要像这样使用一次性模式:
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);
}
答案 5 :(得分:8)
由于类没有获取任何非托管资源(文件,数据库连接等),因此您无需将User
类设为IDisposable
。通常,我们将类标记为
IDisposable
如果他们至少有一个IDisposable
字段或/和属性。
在实施IDisposable
时,最好根据Microsoft的典型方案:
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);
}
}
答案 6 :(得分:3)
只要您想要确定性(已确认)垃圾收集,就会实施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
}
}
创建和使用Users类时,使用&#34;使用&#34;阻止显式调用dispose方法:
using (Users _user = new Users())
{
// do user related work
}
创建的using块的结束用户对象将通过dispose方法的隐式调用来处理。
答案 7 :(得分:0)
我看到了很多Microsoft Dispose模式的例子,这实际上是一种反模式。正如许多人指出的那样,问题中的代码根本不需要IDisposable。但是,如果您打算在哪里实现它,请不要使用Microsoft模式。更好的答案是遵循本文中的建议:
https://www.codeproject.com/Articles/29534/IDisposable-What-Your-Mother-Never-Told-You-About
可能唯一有用的另一件事是抑制代码分析警告... https://docs.microsoft.com/en-us/visualstudio/code-quality/in-source-suppression-overview?view=vs-2017