实现IDisposable接口 - 可释放的字段 vs. 可释放的属性

14

我正在运行VS2013在我的一个项目上的代码分析,并碰到了“CA1001: 拥有可处理字段的类型应该是可处理的”警告。 一个简单的例子可以生成警告(假设DisposableClass实现了IDisposable):

class HasDisposableClassField
{
    private DisposableClass disposableClass;
}

然而,将该字段变量转换为属性后,即使出现属性将由类实例化的情况,也不再生成警告:

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

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

14

是的,缺乏警告是分析工具的局限。

假设你的IDisposable属性没有从其他地方注入,你一定要实现IDisposable并在使用后清理。


9

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

把某个东西放到属性中并不能自动为你处理掉它。

缺少的警告是 Code Analysis 的一个错误(因为它忽略了由编译器生成的后备字段)。


你确定这是一个 bug 而不是故意的吗?也许它没有考虑到 get/set 属性被视为“拥有”可处理对象。 - Gabe
为什么私有的后备字段意味着“所有权”? - Gabe
1
@Gabe:这有什么不同于其他领域的地方吗? - SLaks
@Gabe:但如果您创建一个非自动属性将字段公开(这与自动属性创建的内容相同),它将会警告。 - SLaks
是的,但也许在自动属性上发出警报才是错误。它可能不够聪明,无法识别该字段作为属性公开,从而生成虚假阳性。您能想到任何公开任何IDisposable属性并调用Dispose的类吗? - Gabe
显示剩余4条评论

3

可扔性的实现应取决于需要处理的资源(无论是可扔性还是非托管资源)的创建方式。

如果您的对象通过注入(构造函数、方法或属性)获得资源,那么它可能并不拥有该资源,因此可能不应该对其进行处理。

资源的存储方式(本地变量、字段或属性(带有后备字段))并不重要,但是您可能需要检查您的资源是否已被外部处理,因为您的对象不是其所有者。

如果您的类直接创建资源(通过创建、分配、打开句柄、工厂方法等方式),则它可能拥有该资源,因此可能应该对其进行处理。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接