tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
[ツリー表示へ]  [ワード検索]  [Home]

タイトル Re: PowerPointのオブジェクト開放ができません
投稿日: 2009/08/26(Wed) 22:28
投稿者Hongliang
列挙時は少々ややこしいことになりますね。
For Each は、コンパイル時に GetEnumerator の呼び出しに変換されます。
例えば

For Each mySlide In mySlides
Next

というソースは、大雑把に言って

Dim enumerator As IEnumerator = mySlides.GetEnumerator()
While enumerator.MoveNext()
    Dim mySlide As Object = enumerator.Current
End While

というコードになります。IEnumerator は列挙子と呼ばれます。
このとき、ReleaseComObject で解放する必要がある参照は、
・mySlides が 1 つ
・mySlide が列挙されるごとにそれぞれ 1 つずつ
持っているのは自明ですが、そのほかに GetEnumerator を 1 回呼び出したとき、
・enumerator が 1 つ
・mySlides が追加で 1 つ
増えることになります。
mySlides に関しては単純に ReleaseComObject の呼び出す数を 1 回増やすだけでも
なんとかなりますが、
enumerator の方については、For Each 構文を使った場合
For Each に完全に隠蔽されているので、解放できないと言うことになってしまいます。
ですので、For Each は使用せず、GetEnumerator 及び While ループを使う必要があります。

また、この GetEnumerator で取得した IEnumerator は、
ラップされたマネージなクラスインスタンス(非 COM オブジェクト)だと思います。
// Marshal.IsComObject メソッドで確認してみてください。
IEnumerator 自体が COM オブジェクトでないのであれば、
ReleaseComObject に直接渡すことはできません。
その場合、代わりにこの IEnumerator は
ICustomAdapter インターフェイスも実装しているはずです。
enumerator を ICustomAdapter に TryCast してその GetUnderlyingObject メソッドを呼び出せば、
この列挙子の COM オブジェクト実体が取得でき、ReleaseComObject に渡すことができます。

あと気になるところとしては、
ローカル変数に Nothing を代入する意味は(ほぼ)無いってことでしょうかね。

- 関連一覧ツリー をクリックするとツリー全体を一括表示します)

古いスレッドにレスはつけられません。