Почему я получаю CA2000 с частным членом IDisposable внутри моего класса IDisposable?

У меня есть класс, который реализует IDisposable, потому что у него есть поле частного пользователя "foo", которое IDisposable (которое инициализируется в конструкторе). Я неожиданно получаю ошибку анализа кода CA2000, которая хочет, чтобы я был уверен в утилизации foo. Однако у меня есть foo.Dispose() в моем классе 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"

licensed under cc by-sa 3.0 with attribution.