实现 IDisposable - 可支配领域与可处置属性

本文关键字:属性 IDisposable 可支配 实现 | 更新日期: 2023-09-27 18:30:37

我正在我当前的一个项目上运行VS2013的代码分析,并遇到了"CA1001:拥有可支配字段的类型应该是一次性的。 生成警告(假设DisposableClass实现IDisposable)的简单示例是:

class HasDisposableClassField
{
    private DisposableClass disposableClass;
}

但是,将字段变量转换为属性不再生成警告,即使情况是该属性将由类实例化:

class HasDisposableClassProperty
{
    private DisposableClass disposableClass { get; set; }
    public HasDisposableClassProperty()
    {
        disposableClass = new DisposableClass();
    }
}

在第一种情况下,很明显,类应该实现 IDisposable 模式,并适当地释放其disposableClass字段。 我的问题:缺少第二种情况的警告是代码分析工具的限制吗? 尽管没有警告,但类是否仍应实现 IDisposable 并释放属性?

实现 IDisposable - 可支配领域与可处置属性

是的,缺少警告是分析工具的限制。

假设您的IDisposable属性不是从其他地方注入的,您肯定仍然应该在自己之后实施IDisposable和清理。

是的;你仍然需要处理它。

将某些东西放入属性中并不会神奇地为您处理它。

缺少的警告是代码分析上的错误(它忽略了支持字段,因为它是编译器生成的)

一次性

的实现应取决于如何创建需要处置的资源(无论是一次性的还是非托管的)。

如果对象通过注入(构造函数、方法或属性)接收资源,则它可能不拥有它,因此可能不应释放它。

资源的存储方式(局部变量、字段或属性(带支持字段)并不重要),但是,您可能需要检查资源是否尚未在外部释放,因为您的对象不是其所有者。

如果你的类直接创建一个资源(通过创建、分配、打开句柄、工厂方法),它可能确实拥有它,因此可能应该释放它。

问题在于,大多数静态代码分析工具的规则集有限,因此无法进行此类区分,而是尝试涵盖他们认为更常见的情况。