0

I know this has been discussed many times but no solutions seems to work so I thought and may be worth a try to reopen it since some time has passed.

I have a function:

Public Function Test() As Object
    Dim retVal As DisposableObject
    Dim tempRetVal As DisposableObject
    Try
        tempRetVal = New DisposableObject
        retVal = tempRetVal
        tempRetVal = Nothing
        Return retVal
    Catch
        tempRetVal.Dispose()
        Throw
    Finally
        tempRetVal.Dispose()
    End Try
End Function

As you can see, there are a lot of Dispose statements. This is because I was trying to find a way to have it working. The only way I found (which clearly is not a solution) was to add retVal.Dispose() before returning retval.

 Public Function Test() As Object
    Dim retVal As DisposableObject
    Dim tempRetVal As DisposableObject
    Try
        tempRetVal = New DisposableObject
        retVal = tempRetVal
        tempRetVal = Nothing
        retVal.Dispose()
        Return retVal
    Catch
        tempRetVal.Dispose()
        Throw
    Finally
        tempRetVal.Dispose()
    End Try
End Function

Any hint will be gladly appreciated! :)

Note: I'm using VS2012

EDIT: I also tried the simple template proposed by MS and it doesn't work either:

Public Function Test() As Object
    Dim retVal As DisposableObject
    Dim tempRetVal As DisposableObject
    Try
        tempRetVal = New DisposableObject
        retVal = tempRetVal
        tempRetVal = Nothing
        Return retVal
    Finally
        if tempRetVal isnot Nothing then tempRetVal.Dispose()
    End Try
End Function

CA2000 is thrown on tempRetVal = New DisposableObject.

Rahul
  • 76,197
  • 13
  • 71
  • 125
bkqc
  • 831
  • 6
  • 25

1 Answers1

0

The only way I found (which clearly is not a solution) was to add retVal.Dispose() before returning retval.

Why? You anyways have a finally block defined. Let the finally block take care of the disposal. Your code should look like below. Also,

 Public Function Test() As Object
    Dim retVal As LLServerConnection
    Dim tempRetVal As LLServerConnection
    Try
        tempRetVal = New LLServerConnection
        retVal = tempRetVal
        tempRetVal = Nothing
        Return retVal
    Catch
        Throw
    Finally
        If Not tempRetVal Is Nothing Then
        tempRetVal.Dispose()
    End Try
End Function

See CA2000: Dispose objects before losing scope for more information.

EDIT:

To my believe, you are getting that CA2000 warning message because of the return statement inside TRY block. Rather, return the obejct before your subroutine actually end. See below code with comment added to the changes. This will be fine now.

Public Function Test() As DisposableObject //Change object to actual type DisposableObject
    Dim retVal As DisposableObject = Nothing
    Dim tempRetVal As DisposableObject = Nothing

    Try
        tempRetVal = New DisposableObject()
        retVal = tempRetVal
        tempRetVal = Nothing

    Finally
      If Not tempRetVal Is Nothing Then
         tempRetVal.Dispose()
      End If 

    End Try

        Return retVal //Return the object before your subroutine ends

End Function
Rahul
  • 76,197
  • 13
  • 71
  • 125
  • You're right, in my tests, I tried removing every condition to see if it would change something and forgot to put it back before posting. I agree that my code should look something like this and in fact, I tried it but it still give a CA2000 warning/error. – bkqc Jul 04 '14 at 14:05
  • That's strange. If this is what exactly your code have then Per MSDN it shouldn't through CA2000 any more. Another thought would be removing that empty catch altogether and just have `try .. finally`. see how that works. – Rahul Jul 04 '14 at 23:03
  • As explained in the Edit, I tried it but the message is still there. Something seems to be wrong in the way static analysis detects lost of sight when a value is returned. – bkqc Jul 07 '14 at 21:20