为啥我在 IDisposable 类中获得带有私有成员 IDisposable 的 CA2000?
Posted
技术标签:
【中文标题】为啥我在 IDisposable 类中获得带有私有成员 IDisposable 的 CA2000?【英文标题】:Why am I getting CA2000 with a private member IDisposable inside my IDisposable class?为什么我在 IDisposable 类中获得带有私有成员 IDisposable 的 CA2000? 【发布时间】:2011-01-11 23:04:56 【问题描述】:我有一个实现 IDisposable 的类,因为它有一个 IDisposable 的私有成员字段“foo”(在构造函数中初始化)。我意外地收到 CA2000 代码分析错误,它希望我一定要处理掉 foo。但是,我在班级的 Dispose() 代码中有 foo.Dispose(),它应该会处理这个问题。
我进行了一些搜索,但令人惊讶的是找不到答案。我究竟做错了什么?显然我错过了一些基本的东西。我该如何编写代码来克服这个问题?
我的 VB 代码:
Public Class Bar
Implements IDisposable
Private Foo As SomeDisposableThing
Public Sub New()
Foo = New SomeDisposableThing() With .name = "hello"
End Sub
'''' snip ''''
Private disposedValue As Boolean = False ' To detect redundant calls '
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
If Foo IsNot Nothing Then Foo.Dispose()
End If
End If
Me.disposedValue = True
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
End Class
【问题讨论】:
【参考方案1】:CA2000 错误不是指实现IDisposable
的容器,而是指使用未正确处理的本地。原因是您在一次性对象上使用了对象初始化程序。将生成的实际代码基本上如下
Dim temp = New SomethingDisposable()
temp.Name = "hello"
Foo = temp
此代码被 FxCop 正确标记为在所有情况下都没有正确处理 IDisposable
(temp.Name = "hello"
行可能会发生异常,在这种情况下不会处理)。
解决方法是这里不使用对象初始化器,直接初始化Foo
Foo = New SomethingDisposable()
Foo.Name = "hello"
【讨论】:
呸。消息:不要使用属性:( @Hans,我认为即使它是一个字段,它也会有相同的行为。任何行都可能引发异常(例如ThreadAbort
),所以我猜测 FxCop 会在这里对字段和属性发出同样的警告。不过,还没有测试过这个理论。
@Hans,很有趣。我猜它只会将方法/道具调用标记为危险。
真糟糕! “With”初始化程序应该将其抽象出来。我不必知道“With”初始化程序使用临时变量!以上是关于为啥我在 IDisposable 类中获得带有私有成员 IDisposable 的 CA2000?的主要内容,如果未能解决你的问题,请参考以下文章
C ++:如何在派生类中定义基类构造函数,如果基构造函数具有带有私有成员的初始化列表[重复]
为啥 Enumerable.Range 实现 IDisposable?
为啥 FxCop 坚持使用 IDisposable 作为结构