在 C# 中 parent 类 上正确实现 IDisposable
Implementing IDisposable correctly on parent classes in C#
我有一个 class 实现了 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
,所以我想我应该让我的 class 成为 SerialPort
的 child,但现在我收到警告说我似乎无法修复。
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();
}
}
}
代码警告说 dispose 方法应该是 new
因为它们隐藏了成员,我这样做了,但我也得到:
"Warning CA1063 Ensure that 'AsyncSerial.Dispose()' is declared as public and sealed"
密封意味着它必须被标记为 override
(否则我得到编译器错误),使其覆盖意味着它可以是新的,所以我最终得到:
Error CS0506 'AsyncSerial.Dispose()': cannot override inherited member 'Component.Dispose()' because it is not marked virtual, abstract, or override
我不知道 'correct' 在 parent class 中用 IDisposable
实现处置 class 的方法。我发现的每个例子都只适合以 IDisposable
作为基础,但让我的 class
public class AsyncSerial : SerialPort, IDisposable
{
//code
}
给我一个代码分析警告,因为 SerialPort
已经实现了 IDisposable
.
我是否应该只取消有关确保 'AsyncSerial.Dispose()' 被声明为 public 并密封的警告,或者是否有正确的方法来执行此操作而不会给出代码分析警告。
你的 subclass 应该覆盖 Dispose(bool disposing)
如果有的话——这就是拥有该方法的全部意义,真的。
但是,我怀疑基础 class 无论如何都会做出正确的调用,所以你不需要做任何事情,除非你有额外的资源来释放 没有 于 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
}
请注意,您当前的实现将导致 WhosebugException,因为您的两个 Dispose
重载相互调用。
您不需要在 child class 上声明 public void Dispose()
方法,因为它已经从基础方法中继承了(反正编译器不会让您这样做的) ,除非您使用 new
关键字隐藏基本实现。
如果您不打算处理此 child class 的任何特定内容,则您也不需要覆盖基础 class 的 protected virtual void Dispose(bool)
。
如果您要在 child class 中使用 IDisposable
引用,那么您应该 覆盖 您的基础 class的方法:
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);
}
}
处置模式旨在允许派生类型以一致的方式添加处置逻辑,而不管父类型是否具有 public Dispose
方法或显式实现 IDisposable.Dispose
。从遵循模式的类型派生的类型应该简单地覆盖 Dispose(bool)
而不管父 class 实现如何使用 public 方法或 IDisposable.Dispose()
.[=15 的显式实现=]
虽然 Dispose
模式的设计是基于这样一个有缺陷的假设,即 publicly-exposed 可继承类型的对象通常需要直接合并终结器(而不是将非托管资源封装在私有中-held 私有类型的实例,其目的是清理这些资源),编译器在 C++/CLI(可能还有其他语言)中生成的清理逻辑依赖于该模式,因此将它与可继承的 classes 可能被其他人使用。
我有一个 class 实现了 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
,所以我想我应该让我的 class 成为 SerialPort
的 child,但现在我收到警告说我似乎无法修复。
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();
}
}
}
代码警告说 dispose 方法应该是 new
因为它们隐藏了成员,我这样做了,但我也得到:
"Warning CA1063 Ensure that 'AsyncSerial.Dispose()' is declared as public and sealed"
密封意味着它必须被标记为 override
(否则我得到编译器错误),使其覆盖意味着它可以是新的,所以我最终得到:
Error CS0506 'AsyncSerial.Dispose()': cannot override inherited member 'Component.Dispose()' because it is not marked virtual, abstract, or override
我不知道 'correct' 在 parent class 中用 IDisposable
实现处置 class 的方法。我发现的每个例子都只适合以 IDisposable
作为基础,但让我的 class
public class AsyncSerial : SerialPort, IDisposable
{
//code
}
给我一个代码分析警告,因为 SerialPort
已经实现了 IDisposable
.
我是否应该只取消有关确保 'AsyncSerial.Dispose()' 被声明为 public 并密封的警告,或者是否有正确的方法来执行此操作而不会给出代码分析警告。
你的 subclass 应该覆盖 Dispose(bool disposing)
如果有的话——这就是拥有该方法的全部意义,真的。
但是,我怀疑基础 class 无论如何都会做出正确的调用,所以你不需要做任何事情,除非你有额外的资源来释放 没有 于 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
}
请注意,您当前的实现将导致 WhosebugException,因为您的两个 Dispose
重载相互调用。
您不需要在 child class 上声明 public void Dispose()
方法,因为它已经从基础方法中继承了(反正编译器不会让您这样做的) ,除非您使用 new
关键字隐藏基本实现。
如果您不打算处理此 child class 的任何特定内容,则您也不需要覆盖基础 class 的 protected virtual void Dispose(bool)
。
如果您要在 child class 中使用 IDisposable
引用,那么您应该 覆盖 您的基础 class的方法:
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);
}
}
处置模式旨在允许派生类型以一致的方式添加处置逻辑,而不管父类型是否具有 public Dispose
方法或显式实现 IDisposable.Dispose
。从遵循模式的类型派生的类型应该简单地覆盖 Dispose(bool)
而不管父 class 实现如何使用 public 方法或 IDisposable.Dispose()
.[=15 的显式实现=]
虽然 Dispose
模式的设计是基于这样一个有缺陷的假设,即 publicly-exposed 可继承类型的对象通常需要直接合并终结器(而不是将非托管资源封装在私有中-held 私有类型的实例,其目的是清理这些资源),编译器在 C++/CLI(可能还有其他语言)中生成的清理逻辑依赖于该模式,因此将它与可继承的 classes 可能被其他人使用。