什么时候物品被处理?

时间:2012-09-17 12:30:54

标签: c# oop

我的程序中有以下代码:

//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.Age 之前添加df.Dispose()只是为了看看会发生什么,但我仍然可以访问它。所以我感到困惑?为什么会这样?什么时候物品被处理?

5 个答案:

答案 0 :(得分: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()方法从不调用。

垃圾收集器会在某个时刻找到它,并将调用终结器,它将调用内置的Dispose(bool)模式,但这是winforms的实现细节,而不是妥善处置。

另见MSDN for ShowDialog()

  

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

答案 1 :(得分:3)

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

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

答案 2 :(得分:1)

这是因为您使用ShowDialog(..)来电。

在这种情况下,CLR不会调用表单上的Dispose,以便您从表单中检索至少对话框结果。所以这是唯一一种需要在收盘后明确地调用Dispose(..)的情况。

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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