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,这将调用内置Dispose(bool)模式,但这是 winforms 的实现细节,不是正确的处理方式。

另请参阅MSDNShowDialog()

当窗体显示为模式对话框时,单击关闭按钮(窗体右上角带有 X 的按钮)会导致窗体隐藏并且 DialogResult 属性设置为 DialogResult.Cancel。与非模式表单不同,当用户单击对话框的关闭表单按钮或设置 DialogResult 属性的值时,.NET Framework 不会调用 Close 方法。相反,该表单被隐藏并且可以再次显示而无需创建对话框的新实例。因为显示为对话框的窗体是隐藏的而不是关闭的,所以当您的应用程序不再需要该窗体时,您必须调用该窗体的 Dispose 方法。

于 2012-09-17T12:36:07.473 回答
3

如果您能够调用df.Age,这意味着您持有对对象的引用(df 只是一个引用)。这反过来意味着垃圾收集器不会收集它,因此价值仍然存在。

并且Dispose()不调用垃圾收集器,也不删除引用。Dispose 适用于您的对象需要显式释放某些资源的情况,并且您公开此方法以便可以调用它(而不是通过 GC)。

于 2012-09-17T12:35:17.987 回答
1

这是因为您使用ShowDialog(..)呼叫。

在这种情况下Dispose,CLR 不会调用表单,以便为您提供一种至少从表单中检索对话结果的方法。Dispose(..)因此,这是您需要在关闭后特别调用的唯一情况。

有关这方面的更多信息,您可以阅读社区内容Form.ShowDialog

于 2012-09-17T12:35:34.527 回答
0

垃圾收集器只会收集没有任何东西引用该对象的内存。因此,在您的情况下,您仍然可以在主窗口中引用对话框,直到引用对话框的方法结束为止。

于 2012-09-17T12:35:04.887 回答
0

Dispose 没有任何魔法。这只是一个方法调用。

于 2012-09-17T14:16:12.763 回答