- PR -

Form.Closeメソッドによる破棄とは?

投稿者投稿内容
まどか
ぬし
会議室デビュー日: 2005/09/06
投稿数: 372
お住まい・勤務地: ますのすし管区
投稿日時: 2006-07-06 11:49
#Framework2.0

MSDNによると、Form.Closeメソッドは
「オブジェクト内で作成されたすべてのリソースが閉じ、フォームが破棄されます。」とあります。
また、Form.DialogResultは非表示になるだけとあります。

個人的には、Form自身でMe.Closeとすることは違和感があるので使用せず
Form.DialogResultを設定して、呼び出し元でCloseとDisposeを呼び出すようにしています。

問題は
コード:
Private Sub ShowForm()
    Dim f As New FormChild
    f.ShowDialog()
    Console.WriteLine(f.Prop1)
    f.Dispose()
End Sub

Public Class FormChild

    Private _Prop1 As String = String.Empty

    Public ReadOnly Property Prop1() As String
        Get
            Return _Prop1
        End Get
    End Property

    Private CloseButton_Click(略)
        _Prop1 = "Test"
        Me.Close
    End Sub

End Class


においてProp1を取得できますが、じゃぁCloseで何が破棄されるんだろうかということです。
Closeメソッドの解説に「MDI子フォームについては自分でGCの対象とする必要がある」という特殊条件があるので
それ以外では、たまたまGCに回収される前に参照しているから正しい値が取得できるというのも予想できます。

結果的に欲しい結論は、上記のコードの善悪です。
ご回答お待ちしております。
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2006-07-06 12:15
引用:

においてProp1を取得できますが、じゃぁCloseで何が破棄されるんだろうかということです。



Form のインスタンスがカプセルする各種リソースです。

引用:

結果的に欲しい結論は、上記のコードの善悪です。



特に問題ありません。

上でも書きましたが、一般的な Close() の実装や Dispose() で廃棄されるのはクラスインスタンスではありません。クラスインスタンスがカプセルする各種リソースです。

Close() しようが Dispose() しようが、Form のインスタンスが維持されている限り、Form.Close() や Form.Dispose() による影響を受けないフィールドへのアクセスには何も問題ありません。
まどか
ぬし
会議室デビュー日: 2005/09/06
投稿数: 372
お住まい・勤務地: ますのすし管区
投稿日時: 2006-07-06 13:19
ありがとうございます。
引用:

クラスインスタンスがカプセルする各種リソースです。


これはインスタンス作成の過程で現れるものという認識でよいでしょうか?
つまりコードに書いたものはまったくの対象外であるという問いなんですが。

「カプセルする各種リソース」に関してのポインタ等ご紹介いただけたら幸いです。
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2006-07-06 16:02
引用:

引用:

クラスインスタンスがカプセルする各種リソースです。


これはインスタンス作成の過程で現れるものという認識でよいでしょうか?
つまりコードに書いたものはまったくの対象外であるという問いなんですが。



大雑把にはYESと言えます。

Form クラスの派生クラスに追加したフィールドをどう扱うかは、クラスインスタンスが保持されている限り、基本的に自分の書いたコードによって制御されます。

Close() や IDisposable.Dispose() によってクラスインスタンス自体が廃棄されることはありませんが、派生クラスの FormClosing や FormClosed, IDisposable.Dispose() などでフィールド値を無効にする処理を書いていれば、Close(), Dispose() 後にそのフィールド値は無効になります。

引用:

「カプセルする各種リソース」に関してのポインタ等ご紹介いただけたら幸いです。



「各種リソース」の具体的な明細は、Form クラスの仕様書やソースコードでも手に入れない限り、知ることは出来ません。

どこかで公開されているのかもしれませんが、私は知りません。

Form クラスが Windows OS のウィンドウをカプセル化したものであることは公知の事実なので、最低限内部にウィンドウハンドルを保持しているであろうことは想像に難くないですが、それ以外は分からないです。
まどか
ぬし
会議室デビュー日: 2005/09/06
投稿数: 372
お住まい・勤務地: ますのすし管区
投稿日時: 2006-07-06 16:19
「インスタンス」を破棄するまでメンバにアクセスできるのは当然のこととしていましたが
Closeの説明でちょっと混乱してしまいました。
おっしゃることも理解できましたので解決といたします。

ありがとうございました。
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2006-07-06 19:17
引用:
コード:
    Private CloseButton_Click(略)
        _Prop1 = "Test"
        Me.Close
    End Sub



 FormChild は ShowDialog で開くので、ここで Me.Close は良くないです。
ここは、Me.DialogResult に適切な値を放り込むか、CloseButton.DialogResult プロパティを適切に設定しておきます。


> Form.Dispose() による影響を受けないフィールドへのアクセスには何も問題ありません。
 その影響を受けない範囲を“把握している”なら、問題ないと思います。
しかし、何も考えずに真似をされることを考慮して、
少なくともコミュニティで掲示するコードとしては、
“問題有り”とする方が、問題ないと思います。
ぶさいくろう
ぬし
会議室デビュー日: 2005/11/22
投稿数: 1232
お住まい・勤務地: 川崎市(は俺も含めてロクな人間が住んでないよw)
投稿日時: 2006-07-06 19:28
引用:

Jittaさんの書き込み (2006-07-06 19:17) より:
 FormChild は ShowDialog で開くので、ここで Me.Close は良くないです。


ShowDialogで開くなら呼び出し元でDisposeするんで良くないとは断言できないと思うが?
『望ましいです』ならわかるけどDialogResultで制御が戻ろうとCloseで制御が戻ろうとHideで制御が戻ろうとDisposeはするよね。
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2006-07-06 20:21
引用:

 FormChild は ShowDialog で開くので、ここで Me.Close は良くないです。
ここは、Me.DialogResult に適切な値を放り込むか、CloseButton.DialogResult プロパティを適切に設定しておきます。



値を放り込まなければデフォルト値が返るのが「望んだ動作」なのであれば別に構わないんじゃないすか?

デフォルト値がどんな値か自信がないなら、Load イベント辺りで希望の値を放り込んでおいてもいいだろうし。

# インスタンスの話は被るので割愛。

引用:

> Form.Dispose() による影響を受けないフィールドへのアクセスには何も問題ありません。
 その影響を受けない範囲を“把握している”なら、問題ないと思います。
しかし、何も考えずに真似をされることを考慮して、
少なくともコミュニティで掲示するコードとしては、
“問題有り”とする方が、問題ないと思います。



「問題あり」としたら、Close(), Dispose() 以後、クラスインスタンスのメンバに一切タッチできないことになっちゃいますが、それでは困りませんか?

xxx.Close() 以後、再度 xxx.Open() できないクラスもあれば、出来るクラスもあります。
そういう現実があったとしても「xxx.Close() したらそのインスタンスにはもう触るな」ってことになっちゃいませんか?

原文の上の方でも書きましたが、影響を受けるかどうかは「自分の書いたコード次第」なわけで、影響を受けるかどうかを自分で把握しとくのは当たり前の話なんじゃないかなぁ?

[ メッセージ編集済み 編集者: 渋木宏明(ひどり) 編集日時 2006-07-06 20:25 ]

スキルアップ/キャリアアップ(JOB@IT)