The Two Dot rule unfortunately is not very well documented in msdn. The only mention of it happens to be in the All-In-One Code Framework.


What is Two Dot Rule?


The Two Dots tunnels your call into the Com object model to access it’s properties.

comObject.Property.PropertiesProperty


Let’s take an example

        Dim xlApp As New Excel.Application
        Dim xlWorkBooks As Excel.Workbooks = xlApp.Workbooks
        Dim xlWorkBook As Excel.Workbook = xlWorkBooks.Add()

        '
        '~~> rest of the code
        '

        If Not xlWorkBook Is Nothing Then
            Marshal.FinalReleaseComObject(xlWorkBook)
            xlWorkBook = Nothing
        End If

        If Not xlWorkBooks Is Nothing Then
            Marshal.FinalReleaseComObject(xlWorkBooks)
            xlWorkBooks = Nothing
        End If

        If Not xlApp Is Nothing Then
            Marshal.FinalReleaseComObject(xlApp)
            xlApp = Nothing
        End If

        xlApp.Quit()


Do you notice the two dots? One after the xlApp and the other after Workbooks?

Using Two Dots when calling xlApp.Workbooks.Add creates an RCW (Runtime Callable Wrapper) for the Workbooks object. If you invoke these accessors, the RCW  for Workbooks is created on the GC heap. However what’s worth noting is that the reference is created under the hood on the stack and are then discarded. Because of this there is no way to call MarshalFinalReleaseComObject on this RCW. Therefore, if all references have not been released on the RCW, the COM object does not quit and this results in an instance of your Excel Application (in this case) being left in Task Manager.


Is ignoring Two Dot Rule bad?


Honestly, if I may say so, it all depends on how you flush the toilet after use!

As mentioned above, there is no way to call MarshalFinalReleaseComObject on this RCW. You will have to either force a garbage collection as soon as the calling function is off the stack or you would need to explicitly assign each accessor object to a variable and free it.

Let’s take an example:

 Dim xlApp As New Excel.Application
 Dim xlWorkBooks As Excel.Workbooks = xlApp.Workbooks
 Dim xlWorkBook As Excel.Workbook = xlWorkBooks.Add()

 '
 '~~> rest of the code
 '

 If Not xlWorkBook Is Nothing Then
     Marshal.FinalReleaseComObject(xlWorkBook)
     xlWorkBook = Nothing
 End If

 If Not xlWorkBooks Is Nothing Then
     Marshal.FinalReleaseComObject(xlWorkBooks)
     xlWorkBooks = Nothing
 End If

 If Not xlApp Is Nothing Then
     Marshal.FinalReleaseComObject(xlApp)
     xlApp = Nothing
 End If

 xlApp.Quit()

Having a VBA background, ignoring the two dot rules comes very naturally for me. And there is nothing wrong with it till the time you are doing a Garbage Collection in the end. Let’s take an example.

Imports Excel = Microsoft.Office.Interop.Excel

Public Class Form1
    '~~> Define your Excel Objects
    Dim xlApp As New Excel.Application
    Dim xlWorkBook As Excel.Workbook

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        '~~> Add a New Workbook (IGNORING THE TWO DOT RULE)
        xlWorkBook = xlApp.Workbooks.Add

        '~~> Display Excel
        xlApp.Visible = True

        '~~> Do some stuff Here

        '~~> Save the file
        xlWorkBook.SaveAs(Filename:="C:\Tutorial\SampleNew.xlsx", FileFormat:=51)

        '~~> Close the File
        xlWorkBook.Close()

        '~~> Quit the Excel Application
        xlApp.Quit()

        '~~> Clean Up
        releaseObject(xlApp)
        releaseObject(xlWorkBook)
    End Sub

    '~~> Release the objects
    Private Sub releaseObject(ByVal obj As Object)
        Try
            System.Runtime.InteropServices.Marshal.ReleaseComObject(obj)
            obj = Nothing
        Catch ex As Exception
            obj = Nothing
        Finally
            GC.Collect()
        End Try
    End Sub
End Class

So in the end actually it is up to you which style of coding you like.