2

プログラムに次のコードがあります。

//Dialog Form Class

public int Age;

private void goButtonClick(object sender, EventArgs e)
{
     Age = trackBar1.Value;
     Close();
}

//Main Form Class

DialogForm df = new DialogForm();
df.ShowDialog();
df.Dispose();
if(df.Age >= 18)
{
    //do stuff
}

驚いたことに、df.Age はメソッドによって破棄されるため、アクセスする方法が必要になると思っていましたCloseが、驚くべきことに、この値にアクセスできました。これはガベージコレクターのある種のインテリジェンスであると想定したので、df.Dispose()df.Age を呼び出す前に追加して、何が起こるかを確認しましたが、それでもアクセスできました。それで私は混乱しましたか?なぜこうなった?アイテムが処分されるのはいつですか?

4

5 に答える 5

5

通常、答えは「コードが呼び出すとき.Dispose()」です。これは通常、「ブロックを離れるとき」を意味しusingますが、一部のコードには、破棄される原因となる追加のものがあります。たとえば、winform でShow()メソッドを使用して表示すると、フォームが閉じられたときに破棄されます。

でも!で表示されるフォームの場合ShowDialog()、これは行われません。結局のところ、これはモーダルであるため、予想される寿命は明らかです。

using(var df = new DialogForm())
{
    df.ShowDialog();
    if(df.Age >= 18)
    {
        //do stuff
    }
}

またはそれ以上:

int age;
using(var df = new DialogForm())
{
    df.ShowDialog();
    age = df.Age;
}
if(age >= 18)
{
    //do stuff
}

の戻り値をチェックして、ShowDialog()キャンセルされたかどうかなどを確認することもできます。

しかし、質問に直接答えるには、質問のフォームが適切に破棄されることはありません。IDisposable.Dispose()メソッドが呼び出されることはありません。

ガベージ コレクターはある時点でそれを見つけ、組み込みパターンを呼び出すfinalizerを呼び出しますが、これは winforms の実装の詳細であり、適切な処理ではありません。Dispose(bool)

次の MSDNShowDialog()も参照してください。

フォームがモーダル ダイアログ ボックスとして表示されている場合、[閉じる] ボタン (フォームの右上隅にある X の付いたボタン) をクリックすると、フォームが非表示になり、DialogResult プロパティが DialogResult.Cancel に設定されます。非モーダル フォームとは異なり、Close メソッドは、ユーザーがダイアログ ボックスのフォームを閉じるボタンをクリックしたり、DialogResult プロパティの値を設定したりしたときに、.NET Framework によって呼び出されません。代わりにフォームが非表示になり、ダイアログ ボックスの新しいインスタンスを作成せずに再度表示できます。ダイアログ ボックスとして表示されるフォームは閉じられるのではなく非表示になるため、フォームがアプリケーションで不要になったときに、フォームの Dispose メソッドを呼び出す必要があります。

于 2012-09-17T12:36:07.473 に答える
3

を呼び出すことができる場合df.Age、これはオブジェクトへの参照を保持していることを意味します (df は単なる参照です)。これは、ガベージ コレクターがそれを収集しないことを意味するため、値はまだそこにあります。

ガベージ コレクターを呼び出したり、Dispose()参照を削除したりしません。Dispose は、オブジェクトが一部のリソースを明示的に解放する必要があり、このメソッドを公開して (GC ではなく) 呼び出せるようにする場合に使用します。

于 2012-09-17T12:35:17.987 に答える
1

これは、ShowDialog(..)通話を使用するためです。

この場合、フォームは CLR によって呼び出されず、フォームから少なくともダイアログの結果Disposeを取得する方法を取得します。したがって、クローズ後に明示的に呼び出す必要があるのはこれだけです。Dispose(..)

詳細については、コミュニティ コンテンツForm.ShowDialogを参照してください。

于 2012-09-17T12:35:34.527 に答える
0

Dispose に関連する魔法はありません。ただのメソッド呼び出しです。

于 2012-09-17T14:16:12.763 に答える
0

ガベージ コレクターは、そのオブジェクトへの参照を何も保持していないメモリのみを収集します。したがって、あなたの場合、ダイアログを参照するメソッドが終了するまで、メインウィンドウにダイアログへの参照が残っています。

于 2012-09-17T12:35:04.887 に答える