C# 实现IDisposable-一次性字段与一次性属性

C# 实现IDisposable-一次性字段与一次性属性,c#,C#,我在当前的一个项目上运行VS2013的代码分析,遇到了“CA1001:拥有一次性字段的类型应该是一次性的。”生成警告的一个简单示例(假定DisposableClassimplementsIDisposable)是: 但是,将字段变量转换为属性不再生成警告,即使情况是该属性将由类实例化: class HasDisposableClassProperty { private DisposableClass disposableClass { get; set; } public Ha

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

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

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

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

是;你仍然需要处理它

把某物放进一处房产并不能神奇地为你处置它


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

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


如果您的
IDisposable
属性不是从其他地方注入的,您肯定仍然应该实施
IDisposable
并在自己完成后进行清理。

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

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

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

如果您的类直接创建了一个资源(通过create、allocate、openhandle、factory方法),那么它很可能拥有它,因此应该处理它


问题是大多数静态代码分析工具都有有限的规则集,因此不能做出这样的区分,而是试图覆盖他们认为更常见的情况。

你确定这是一个bug而不是故意的吗?也许它不认为GET/SET属性是“拥有”一次性对象。@ Gabe:是的,但是它应该从编译器生成的支持域报告它。为什么私有支持字段暗示“所有权”?@ Gabe:它与其他字段有什么不同?这个警告是专门针对拥有<代码> IDSistabue< /C>的类的。这可能有点难以定义,但是有一个实现了
IDisposable
类型的私有字段是一个很好的指标,表明您应该负责处理它,因为可能没有其他人引用它。仅仅拥有类型为
IDisposable
的get/set属性并不意味着您拥有它,因为任何人都可以设置或获取对它的引用。
class HasDisposableClassProperty
{
    private DisposableClass disposableClass { get; set; }
    public HasDisposableClassProperty()
    {
        disposableClass = new DisposableClass();
    }
}