我的程序中有以下代码:
//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()
只是为了看看会发生什么,但我仍然可以访问它。所以我感到困惑?为什么会这样?什么时候物品被处理?
答案 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的实现细节,而不是妥善处置。
当窗体显示为模式对话框时,单击“关闭”按钮(窗体右上角带有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没有任何魔力。这只是一个方法调用。