Excelの遅延バインディングで「DisconnectedContext 検出」エラー(続き)

<私の別ブログ 2014年03月19日からの引っ越し記事です>

前回の記事で、dynamic型変数に格納したCOMオブジェクトを解放する際に出るエラーを、明示的なキャストにより回避できることろまでわかった。

そこで、今回は、キャストの有無で、コンパイル結果にどのような影響があるのかをILDASMでC#のコンパイル結果を確認してみた。

比較対象1:キャストなし

            // COMオブジェクト解放
            Marshal.ReleaseComObject(xlWorbook);
            Marshal.ReleaseComObject(xlWorkbooks);
            Marshal.ReleaseComObject(xlApp);

比較対象2:すべてをキャスト

            // COMオブジェクト解放
            Marshal.ReleaseComObject((object)xlWorbook);
            Marshal.ReleaseComObject((object)xlWorkbooks);
            Marshal.ReleaseComObject((object)xlApp);

まず、上記2つの処理をそれぞれコンパイルしてexeを作成。その後、それぞれのexeファイルをILDASMでダンプし、WinMergeで比較した。

下記は、左は「キャストなし」、右は「すべてをキャスト」の比較結果である。

上記比較結果より、dynamic型の変数をキャストせず Marshal.ReleaseComObject() に直接渡す場合、不要(?)な処理がたくさん行われていることが分かった。

差分の詳細は以下の通り。「すべてをキャスト」(右側)のコンパイル結果は非常にシンプルである。

ちなみに、Marshal.ReleaseComObject()でCOMオブジェクトを解放する処理を、事前バインディングで記述した場合のコンパイル結果は以下のようになった。

赤枠内の Marshal.ReleaseComObject()  を呼び出す処理は、遅延バインディングでdynamic変数をobject型にキャストした場合と同じである。

また、MSDNで、「dynamic 型の変数は object 型の変数にコンパイルされます。 そのため、dynamic 型はコンパイル時にのみ存在し、実行時には存在しません。」という記載を見つけた。dynamic 型は、最終的にはobject型にコンパイルされるのであれば、最初からキャストしておいても良いのではないだろうか。

これらのことから、Marshal.ReleaseComObject() を呼び出す際は、dynamic型変数をobject型にキャストしても問題無いだろうと考えている。

参照
MSDN  dynamic (C# リファレンス)
http://msdn.microsoft.com/ja-jp/library/dd264741.aspx
 dynamic 型の変数は object 型の変数にコンパイルされます。 そのため、dynamic 型はコンパイル時にのみ存在し、実行時には存在しません。

タイトルとURLをコピーしました