我的程序中有以下代码:

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

#1楼 票数: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.Cancel。 与非模态窗体不同,当用户单击对话框的关闭窗体按钮或设置DialogResult属性的值时,.NET Framework不会调用Close方法。 而是隐藏表单,并且可以在不创建对话框的新实例的情况下再次显示该表单。 因为显示为对话框的窗体是隐藏而不是关闭的,所以当应用程序不再需要该窗体时,必须调用窗体的Dispose方法。

#2楼 票数:3

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

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

#3楼 票数:1

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

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

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

#4楼 票数:0

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

#5楼 票数:0

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

  ask by rtuner translate from so

未解决问题?本站智能推荐:

4回复

你什么时候以及为什么要密封一个类?

在C#和C ++ / CLI关键字sealed (或NotInheritable在VB)用于保护一类从任何继承机会(类将是非可继承)。 我知道面向对象编程的一个特性是继承,我觉得sealed的使用违背了这个特性,它停止了继承。 是否有示例说明了sealed的好处以及何时使用它很重要?
4回复

OOP C#为什么我的物品为公开物品时出现保护等级错误

错误1'pregatiret.Elev.Elev(string,int)'由于其保护级别c:\\ users \\ marius \\ documents \\ visual studio 2012 \\ Projects \\ pregatiret \\ pregatiret \\ Fo
3回复

什么时候我们需要实现abastract类,什么时候Interface

可能重复: 抽象类与接口 抽象类和接口类? 大家好,当我们需要实现抽象类和接口时,我对抽象类和接口的使用有点困惑。 感谢Vijendra Singh
5回复

你什么时候定义一个班级?

假设你想写一个俄罗斯方块克隆,你刚开始计划。 你如何决定什么应该是一个班级? 您是将单个块设为类还是仅使用不同的块类型? 我问这个是因为我经常发现自己编写的课程太多,或者写的课程太少。
5回复

当我需要某些物品时,我应该只使用它的“ int id”吗?

我的应用程序具有InstrumentFactory创建Instrument实例的唯一位置。 每个乐器实例都包含几个字段,例如Ticker=MSFT和GateId=1以及唯一的Id =1 。 现在,我意识到我几乎不再需要Instrument实例。 在90%的情况下,我只需要Id 。 例
2回复

OOP紧耦合。 我什么时候应该做?

我已经实施了两项服务。 一个从Country API中提取数据,另一个从County API中提取数据。 我喜欢保持控制器整洁,因此很好奇将服务组合在一起而不是分开放置是个好主意。 我不确定是什么构成紧密的耦合以及何时合适。 我应该沿着这条路线走吗: 要么
4回复

我什么时候应该使用抽象工厂模式

我一直在阅读抽象工厂模式,但即使我理解它,我也不知道何时使用它。 模式的定义说它用于抽象对象实例化,但我不清楚为什么我需要这样做,我为什么要关心对象实例化以及为什么(或何时)对抽象很重要它。
8回复

什么时候应该写静态方法?

所以我理解静态方法或字段是什么,我只是想知道何时使用它们。 也就是说,在编写代码时,设计适合使用静态方法和字段。 一种常见的模式是使用静态方法作为静态工厂,但这可以通过重载构造函数来轻松完成。 正确? 例如: 至于静态场,是否最好使用singelton-objects?