【问题标题】:Implementing IDisposable - Disposable Fields vs. Disposable Properties实现 IDisposable - 一次性字段与一次性属性
【发布时间】:2014-11-17 16:46:26
【问题描述】:

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

class HasDisposableClassField
{
    private DisposableClass disposableClass;
}

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

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

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

【问题讨论】:

    标签: c#


    【解决方案1】:

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

    假设您的 IDisposable 属性没有从其他地方注入,您绝对应该仍然实现 IDisposable 并自行清理。

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

      • 您确定这是一个错误而不是故意的吗?也许它不认为 get/set 属性是“拥有”一次性对象。
      • @Gabe:是的,但它应该从编译器生成的支持字段中报告它。
      • 为什么私有支持字段暗示“所有权”?
      • @Gabe:它与任何其他领域有什么不同?
      • 警告专门针对拥有 IDisposable 的类。这可能有点难以定义,但是拥有一个实现 IDisposable 类型的私有字段是一个很好的指标,表明您应该负责处理它,因为它可能没有其他人引用它。仅仅拥有 IDisposable 类型的 get/set 属性并不意味着您拥有它,因为任何人都可以设置或获取对它的引用。
      【解决方案3】:

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

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

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多