使用Dispose()方法从窗体中移除控件。

3

使用Dispose()方法从Form中移除Control是正确的吗?

例如,我在表单中有一个名为'button1'的按钮。当调用Dispose()方法时,它会立即从表单和表单的'Controls'-集合中消失。但这总是这种情况吗?或者还有其他情况(可能是其他控件),垃圾回收器需要一些时间吗?


我更喜欢隐藏而不是丢弃。 - M.kazem Akhgary
3个回答

3

"Control.Dispose"方法的这个“奖励”没有被记录在文档中。

一般来说,您不应该建立您的程序基于未记录的行为在将来保持不变,甚至跨越所有当前控件的实现期望。

然而,正如您可以从Control.Dispose(bool)的参考源代码中看到:

if (parent != null) {
    parent.Controls.Remove(this);
}

这确实在当前实现中发生了。

但是,这并非是记录下来的行为。您可以根据自己的理解进行操作。


所以我将使用'Controls.Remove(button1)',然后将剩下的交给垃圾回收器。我只是想知道为什么Dispose()对我有效。谢谢! - user1027167
2
@user1027167 - 单纯移除一个控件是不够的,你仍然需要调用 Control.Dispose 方法。 - Joe
@Joe:我以为垃圾回收器会调用终结器,而终结器应该调用Dispose方法。如果我调用Dispose(),我必须确保没有其他人引用了这个控件。而这正是垃圾回收器的工作。难道我错了吗? - user1027167
1
你绝不能让可丢弃的对象随意放置,直到终结器来处理它们。你应该始终进行妥善的处理。 - Lasse V. Karlsen
@HenkHolterman 我完全同意,并且由于这个行为是在 Control.Dispose 中实现的,你无论在任何情况下都应该调用它,所以它将被删除。但是再次强调,这是未记录的行为. - Lasse V. Karlsen

3

来自MSDN

此方法由公共 Dispose 方法和 Finalize 方法调用。Dispose 使用 disposing 参数设置为 true 调用受保护的 Dispose(Boolean) 方法。Finalize 使用 disposing 设置为 false 调用 Dispose。

所以我认为没有问题。


1

你应该调用Dispose()吗?

每当你看到实现了System.IDisposable接口的类时,你应该假设这个类的设计者认为这个类可能持有一些稀缺资源。

你不必调用这些类的对象的Dispose()方法。如果你不调用,最终器会自动调用它。然而,如果你不调用Dispose(),稀缺资源将被持有的时间比需要的时间更长,可能导致资源不足。

因此,在将Control赋值为null之前,确实应该调用Control.Dispose()。

在释放控件之前,你应该从控件集合中移除控件吗?

显然,当前的实现确保已释放的控件从control.Parent.Controls的控件集合中移除。

然而,根据你的实现,你确定你添加控件的ControlCollection不是System.Windows.Forms.Control.ControlCollection的子类,具有稍微不同的行为吗?毕竟:ControlCollection并没有被密封。即使你使用自己的控件集合创建了自己的窗体,其他人可能会从你的窗体派生出带有自己ControlCollection的窗体。

因此,为了确保遵循处理ControlCollection的规则,我认为在释放控件之前应该将其从集合中移除。

// Create myControl and add to myForm
var myControl = new MyControl(...);
myControl.SetProperties
myForm.Controls.Add(myControl);

// proper removal:
// if someone else could already have removed the control:
// add a check if it is still there.
myForm.Control.Remove(myControl);
myControl.Dispose();    // no problem if already disposed
myControl = null;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接