Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why am I getting CA2000 with a private member IDisposable inside my IDisposable class?

I have a class that implements IDisposable because it has a private member field "foo" that is IDisposable (which is initialized in the constructor). I am unexpectedly getting a CA2000 Code Analysis error, which wants me to be sure to dispose of foo. However, I have foo.Dispose() in my class's Dispose() code, which should take care of this.

I did some searching around and surprisingly can't find an answer. What am I doing wrong? Clearly I missing something basic. How do I write my code to overcome this?

My VB code:

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
like image 474
Patrick Szalapski Avatar asked Jan 11 '11 23:01

Patrick Szalapski


1 Answers

The CA2000 error doesn't refer to the container implementing IDisposable but rather the use of a local which is not properly disposed. The reason why is that you are using an object initializer on the disposable object. The actual code that will get generated is essentially the following

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

This code is correctly flagged by FxCop as not properly disposing of an IDisposable in all instances (it's possible for an exception to occur on the temp.Name = "hello" line in which case it wouldn't be disposed).

The fix is to not use an object initializer here and initialize Foo directly

Foo = New SomethingDisposable()
Foo.Name = "hello"
like image 173
JaredPar Avatar answered Oct 14 '22 01:10

JaredPar