C# 如果终结器不是';没有实施?
虽然Dispose模式在Internet和SOF上被广泛讨论,但我找不到任何资源来回答我的问题 因此,请在将本文件标记为副本之前通读到底。如果你能给我指出我之前遗漏的一个问题,我将很高兴地删除这个问题C# 如果终结器不是';没有实施?,c#,.net,memory-leaks,garbage-collection,dispose,C#,.net,Memory Leaks,Garbage Collection,Dispose,虽然Dispose模式在Internet和SOF上被广泛讨论,但我找不到任何资源来回答我的问题 因此,请在将本文件标记为副本之前通读到底。如果你能给我指出我之前遗漏的一个问题,我将很高兴地删除这个问题 我见过许多类(盲目地?)实现dispose模式而不实现终结器 报告说: 布尔参数disposing指示是从IDisposable.Dispose实现还是从终结器调用该方法。Dispose(bool)实现应该在访问其他引用对象(例如,前面示例中的resource字段)之前检查参数。仅当从IDisp
我见过许多类(盲目地?)实现dispose模式而不实现终结器 报告说: 布尔参数disposing指示是从IDisposable.Dispose实现还是从终结器调用该方法。Dispose(bool)实现应该在访问其他引用对象(例如,前面示例中的resource字段)之前检查参数。仅当从IDisposable.Dispose实现调用该方法时(当disposing参数等于true时),才应访问此类对象如果从终结器调用该方法(disposing为false),则不应访问其他对象。原因是对象是以不可预测的顺序完成的,因此它们或它们的任何依赖项可能已经完成 据我所知,GC调用finalizer方法(如果实现的话),而finalizer方法反过来应该调用参数为false的Dispose(bool)方法 我的第一个问题是,如果一个类没有实现终结器,那么Dispose(bool)是否曾经被调用,参数为false?(例如,通过CLR中我没有遇到的某些内容) 我知道Dispose(bool)可以用来确保对象只被处理一次 因此,我的第二个问题是,如果一个类不需要实现终结器,那么它可以简单地实现如下所示的Dispose方法吗?
private bool objectDisposed;
public void Dispose()
{
if (!objectDisposed)
{
// Release/dispose managed resources
// ...
// ...
objectDisposed = true;
}
}
我的第一个问题是,如果类没有实现终结器,那么
Dispose(bool)是否曾经被调用,参数为false?(例如。
通过CLR中我没有遇到的东西)
没有
因此,我的第二个问题是类是否不需要实现
然后,终结器可以简单地实现Dispose方法,如
下面
我不会,但你可以。如果您这样做了,您将重新发明IDisposable模式,如果这个类要扩展的话。正如HansPassant在评论中指出的,如果存在派生类,IDisposable模式非常方便。我宁愿一开始就遵循这种模式
基类
using System;
class BaseClass : IDisposable
{
// Flag: Has Dispose already been called?
bool disposed = false;
// Public implementation of Dispose pattern callable by consumers.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing) {
// Free any other managed objects here.
//
}
// Free any unmanaged objects here.
//
disposed = true;
}
// Only if there are unmanaged resources.
~BaseClass()
{
Dispose(false);
}
}
using System;
class DerivedClass : BaseClass
{
// Flag: Has Dispose already been called?
bool disposed = false;
// Protected implementation of Dispose pattern.
protected override void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing) {
// Free any other managed objects here.
//
}
// Free any unmanaged objects here.
//
disposed = true;
// Call the base class implementation.
base.Dispose(disposing);
}
// Only if there are unmanaged resources.
~DerivedClass()
{
Dispose(false);
}
}
派生类
using System;
class BaseClass : IDisposable
{
// Flag: Has Dispose already been called?
bool disposed = false;
// Public implementation of Dispose pattern callable by consumers.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing) {
// Free any other managed objects here.
//
}
// Free any unmanaged objects here.
//
disposed = true;
}
// Only if there are unmanaged resources.
~BaseClass()
{
Dispose(false);
}
}
using System;
class DerivedClass : BaseClass
{
// Flag: Has Dispose already been called?
bool disposed = false;
// Protected implementation of Dispose pattern.
protected override void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing) {
// Free any other managed objects here.
//
}
// Free any unmanaged objects here.
//
disposed = true;
// Call the base class implementation.
base.Dispose(disposing);
}
// Only if there are unmanaged resources.
~DerivedClass()
{
Dispose(false);
}
}
我的第一个问题是,如果类没有实现终结器,那么
Dispose(bool)是否曾经被调用,参数为false?(例如。
通过CLR中我没有遇到的东西)
没有
因此,我的第二个问题是类是否不需要实现
然后,终结器可以简单地实现Dispose方法,如
下面
我不会,但你可以。如果您这样做了,您将重新发明IDisposable模式,如果这个类要扩展的话。正如HansPassant在评论中指出的,如果存在派生类,IDisposable模式非常方便。我宁愿一开始就遵循这种模式
基类
using System;
class BaseClass : IDisposable
{
// Flag: Has Dispose already been called?
bool disposed = false;
// Public implementation of Dispose pattern callable by consumers.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing) {
// Free any other managed objects here.
//
}
// Free any unmanaged objects here.
//
disposed = true;
}
// Only if there are unmanaged resources.
~BaseClass()
{
Dispose(false);
}
}
using System;
class DerivedClass : BaseClass
{
// Flag: Has Dispose already been called?
bool disposed = false;
// Protected implementation of Dispose pattern.
protected override void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing) {
// Free any other managed objects here.
//
}
// Free any unmanaged objects here.
//
disposed = true;
// Call the base class implementation.
base.Dispose(disposing);
}
// Only if there are unmanaged resources.
~DerivedClass()
{
Dispose(false);
}
}
派生类
using System;
class BaseClass : IDisposable
{
// Flag: Has Dispose already been called?
bool disposed = false;
// Public implementation of Dispose pattern callable by consumers.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing) {
// Free any other managed objects here.
//
}
// Free any unmanaged objects here.
//
disposed = true;
}
// Only if there are unmanaged resources.
~BaseClass()
{
Dispose(false);
}
}
using System;
class DerivedClass : BaseClass
{
// Flag: Has Dispose already been called?
bool disposed = false;
// Protected implementation of Dispose pattern.
protected override void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing) {
// Free any other managed objects here.
//
}
// Free any unmanaged objects here.
//
disposed = true;
// Call the base class implementation.
base.Dispose(disposing);
}
// Only if there are unmanaged resources.
~DerivedClass()
{
Dispose(false);
}
}
将回答您的所有问题(编辑:链接到wayback版本,因为格式是正确的)谢谢各位,我已经阅读了第一个。简单的回答是“不!”模式的病毒功能可能会出现问题,如果一个基类实现了,并且您的派生类也有要处理的东西,那么您只能重写dispose(bool)方法,它们当然可以。问题的起因是Dispose()在基类中通常不声明为virtual。因此,如果客户机代码将派生类对象存储在基类引用中并调用Dispose(),则只执行基类的Dispose()方法。处置模式要求处置(bool)是虚拟的。将回答您的所有问题(编辑:链接到wayback版本,因为格式是正确的)谢谢各位,我已经阅读了第一个。简单的回答是“不!”模式的病毒功能可能会出现问题,如果一个基类实现了,并且您的派生类也有要处理的东西,那么您只能重写dispose(bool)方法,它们当然可以。问题的起因是Dispose()在基类中通常不声明为virtual。因此,如果客户机代码将派生类对象存储在基类引用中并调用Dispose(),则只执行基类的Dispose()方法。处置模式要求Dispose(bool)是虚拟的。要么这样,要么将类密封起来,使其无法扩展。我们真的必须摆脱这种处置模式的胡说八道,这个答案无助于我们达到目的。新规则:如果不密封该类,则始终将Dispose()方法设置为虚拟。C++中的标准规则,要么是使这个类被密封,要么使它不能扩展。我们真的必须摆脱这种处理模式的胡说,这个答案不能帮助我们到达那里。新规则:如果不密封该类,则始终将Dispose()方法设置为虚拟。C++ BTW中的标准规则