What is best (or commonly accepted) practice for where to declare COM object variables (scope) and how to handle cleaning them up when using structured error handling?I just spend a whole load of time learning about Garbage Collection and Reference Counting and dealing with releasing COM objects in .NET. Working with COM is annoying...The DilemmaI realize it's important to release referenced COM objects after finishing with them.  I also realize it's also important to anticipate and handle errors.These two things together seem to be at odds with what keeps getting beaten into my head as best practice:  declaring your variables where they are used. Now, in order to ensure the references are released when done with them, it seems to make the most sense to do this cleanup within the Finally portion of a Try/Catch block.  However, doing so means that I cannot declare these variables within the Try or Catch portions of the block because they will not be accessible to the Finally portion.  SO....Where does that leave me with regards to following best practices? Should I continue to declare variables at the beginning of each routine in order to clean them up using Finally?Is there some other method of accessing COM references at the end of a procedure?Am I just picking pepper out of fly shit with regards to best practices?Example CodeIn Example 1, I've declared all my variables before entering the Try/Catch block.  This way I can ensure they get cleaned up, regardless of any errors. In Example 2, I've declared my variables where they are used, but this causes a problem with potential non-release of COM objects. Imports System.Runtime.InteropServicesModule COMexamples       Sub Example1()        Dim Com1 As SomeCOM        Dim Com2 As AnotherCOM        Try            Com1 = New SomeCOM            Com1.DoSomeStuff()        Catch ex As Exception            Com2 = New AnotherCOM            Com2.CleanupTheMess()        Finally            If Not Com1 Is Nothing Then                Com1.Close()                Marshal.FinalReleaseComObject(Com1)            End If            If Not Com2 Is Nothing Then                Com2.Quit()                Marshal.FinalReleaseComObject(Com2)            End If        End Try    End Sub    Sub Example2()        Try            Dim Com1 As New SomeCOM            Com1.DoSomeStuff()            'If an exception is thrown, the object won't get released!            Com1.Close()            Marshal.FinalReleaseComObject(Com1)        Catch ex As Exception            Dim Com2 As New AnotherCOM            Com2.CleanupTheMess()            'Another exception here means we miss releasing this COM reference too!            Com2.Quit()            Marshal.FinalReleaseComObject(Com2)        Finally            'This is pretty much useless now as Com1 and Com2 are out of scope here        End Try    End SubEnd Module
COM - with great power comes great responsibility, but at what cost? (looking for advice on coding practices when working with COM)
object oriented design;garbage collection;com;reference counting
You should declare and create the object before the try-block. This is not specifically for com, but a general principle when using a resource that must explicitly be deallocated in a finally block. In other words - first create the resource, and if that succeeds you try to use the resource. On the other hand, if resource allocation fails, the try/finally block is never executed.This also relieves you from checking if Com1 or Com2 is assigned in the finally block - you know for sure that if you enter the try block that the object has been initialized.Sub Example()    Dim Com1 As New SomeCOM    Try        Com1.DoSomeStuff()    Catch        Cleanup()    Finally        Com1.Close()        Marshal.FinalReleaseComObject(Com1)    End TryEnd SubSub Cleanup()    Dim Com2 As New AnotherCOM    Try        Com2.CleanUpTheMess()    Finally        Com2.Quit()        Marshal.FinalReleaseComObject(Com2)    End TryEnd Sub