Почему я получаю CA2000 с закрытым членом IDisposable внутри моего класса IDisposable? - PullRequest
7 голосов
/ 12 января 2011

У меня есть класс, который реализует 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 Ответ

7 голосов
/ 12 января 2011

Ошибка CA2000 относится не к контейнеру, реализующему IDisposable, а скорее к использованию локального сервера, который неправильно расположен.Причина в том, что вы используете инициализатор объекта для одноразового объекта.Фактический код, который будет сгенерирован, по сути следующий:

Dim temp = New SomethingDisposable()
temp.Name = "hello"
Foo = temp

. Этот код правильно помечен FxCop как неправильное удаление IDisposable во всех случаях (возможно, исключение может произойти вСтрока 1006 *, в этом случае она не будет уничтожена).

Исправление состоит в том, чтобы не использовать здесь инициализатор объекта и инициализировать Foo напрямую

Foo = New SomethingDisposable()
Foo.Name = "hello"
...