我有一个实现C#SerialPort
的类,它曾经是这样的:
public class AsyncSerial : IDisposable
{
SerialPort newPort; //Parameters declared in my constructor
//Constructor and other methods
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if(disposing)
{
this.Close();
this.Dispose();
}
}
}
这在代码分析中不会引发任何警告(我从MSDN获取了代码,作为如何正确执行此操作的示例)。
因为我只会宣布一个SerialPort
我认为我会让我的班级成为SerialPort
的孩子,但现在我收到警告,我似乎无法修复。
public class AsyncSerial : SerialPort
{
//Constructor and other methods
public new void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected new virtual void Dispose(bool disposing)
{
if(disposing)
{
this.Close();
this.Dispose();
}
}
}
代码警告说处理方法应该是new
,因为它们隐藏了成员,我做了,但我也得到了:
“警告CA1063确保'AsyncSerial.Dispose()'被声明为公共密封”
使其密封意味着它必须被标记为override
(或者我得到编译器错误),使其覆盖意味着它可以是新的,所以我最终得到:
错误CS0506'AsyncSerial.Dispose()':无法覆盖继承的成员'Component.Dispose()',因为它未标记为虚拟,抽象或覆盖
我不知道在父类中使用IDisposable
的类实现处理的'正确'方法。我找到的每个例子都只适合IDisposable
作为基础,但是我的班级
public class AsyncSerial : SerialPort, IDisposable
{
//code
}
给了我一个代码分析警告,因为SerialPort
已经实现了IDisposable
。
我是否应该禁止关于确保'AsyncSerial.Dispose()'被声明为公共和密封的警告,或者是否有正确的方法来执行此操作而不提供代码分析警告。
答案 0 :(得分:8)
如果有的话,你的子类应该覆盖Dispose(bool disposing)
- 这就是拥有该方法的全部意义,真的。
但是,我怀疑基类会进行正确的调用,所以你不需要做任何事情,除非你有额外的资源来释放{em>不是在{{ 1}}。如果是这种情况,请在Close()
中执行此操作:
Dispose(bool disposing)
请注意,当前两个protected override void Dispose(bool disposing)
{
// Allow the base class to release resources
base.Dispose(disposing);
// Release any extra resources here
}
重载相互调用时,您当前的实现将导致StackOverflowException。
答案 1 :(得分:1)
Dispose Pattern旨在允许派生类型以一致的方式添加处理逻辑,而不考虑父类型是否具有公共Dispose
方法或显式实现IDisposable.Dispose
。从模式后面的类型派生的类型应该简单地覆盖Dispose(bool)
,无论父类如何使用公共方法或IDisposable.Dispose()
的显式实现。
虽然Dispose
模式的设计是基于有缺陷的假设,即公开暴露的可继承类型对象通常需要直接合并终结器(而不是将非托管资源封装在私有类型的私有类型中,而非私有类型的私有类型目的是清理那些资源),C ++ / CLI中编译器生成的清理逻辑(也可能是其他语言)依赖于模式,因此将它与可由其他人使用的可继承类一起使用是个好主意。
答案 2 :(得分:0)
你不需要在子类上声明一个public void Dispose()
方法,因为它已经从基类继承了(编译器不会让你反正,除非你隐藏了基础使用new
关键字实现。
如果您不打算处理此子类的任何特定内容,您也不需要覆盖基类protected virtual void Dispose(bool)
。
如果您的子课程中有IDisposable
引用,那么您应该覆盖您的基类的方法:
public class AsyncSerial : SerialPort, IDisposable
{
// SomeClass implements IDisposable
private SomeClass _disposableInstance;
// ...
protected override void Dispose(bool disposing)
{
if(disposing)
{
if(_disposableInstance != null)
_disposableInstance.Dispose();
}
// Call the base Dispose, to release resources on the base class.
base.Dipose(disposing);
}
}