C# 具体什么时候处理一件物品?
我的程序中有以下代码:C# 具体什么时候处理一件物品?,c#,oop,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 >
//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()
,只是想看看会发生什么,但我仍然可以访问它。所以我迷糊了?为什么会这样?一个项目到底什么时候被释放?垃圾收集器只会在没有任何东西包含对该对象的引用的情况下收集内存。因此,在您的情况下,在引用对话框的方法结束之前,您的主窗口中仍然有对对话框的引用。如果您能够调用df.Age
,这意味着您保留了对对象的引用(df只是一个引用)。这反过来意味着垃圾收集器不会收集它,因此该值仍然存在
并且
Dispose()
不会调用垃圾收集器,也不会删除引用。Dispose用于对象需要显式释放某些资源的情况,并且您公开此方法以便可以调用它(而不是通过GC)。这是因为您使用ShowDialog(…)
调用
在这种情况下,CLR不会调用窗体上的Dispose
,以获得至少从窗体检索对话框结果的方法。因此,这是在关闭后需要专门调用Dispose(..)
的唯一情况
关于这方面的更多信息,您可以阅读社区内容。通常,答案是“当您的代码调用.Dispose()
”,这通常意味着“当它使用块离开时”,但是有些代码有额外的东西导致它被处置。例如,在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.Cancel。与非模态窗体不同,当用户单击对话框的关闭窗体按钮或设置DialogResult属性的值时,.NET Framework不会调用Close方法。相反,窗体是隐藏的,可以再次显示,而无需创建对话框的新实例。由于显示为对话框的窗体是隐藏的而不是关闭的,因此当应用程序不再需要该窗体时,必须调用该窗体的Dispose方法
处置不涉及魔法。这只是一个方法调用。Dispose
一个垃圾收集。一个项目什么时候被处理?调用Dispose
方法时。但是请不要把垃圾处理误认为是垃圾收集。收集的垃圾从来不会“处理”任何东西,如果我们说的“处理”是指IDisposable
是的,我想我的英语技能有点扭曲了答案。这正是我要找的答案。谢谢但令人困惑的是,MSDN说您在不再需要Dispose方法时调用了Dispose方法,但您说它从未被正确地处理过?@rtuner,因为在您问题中的代码中,您没有调用Dispose()
,也没有使用块使用。因此:它永远不会被处置。您的工作就是通过这种或那种方式调用Dispose()
。嗯,我提到我在代码中手动调用了Dispose
。请参阅编辑的版本。它不影响我是否可以访问它:/?@rtuner right;通过您的编辑,一切都取决于.Age
的实现方式。如果这是一个领域的支持,那么它将是罚款;如果它由一个控件支持,那么由于子控件将被释放,它可能会出错。但重要的是,处置与收集无关。你明白我的意思吗?