使用 Dispose() 从表单中删除控件

Using Dispose() to remove Control from Form

使用 Dispose() 从表单中删除控件是否正确?

例如我的公式上有一个按钮 'button1'。调用 Dispose() 时,它会立即从表单中消失,也会从表单的 'Controls'-Collection 中消失。但情况总是如此吗?或者是否有其他情况(可能是其他控件)GC 等待一段时间?

来自MSDN

This method is called by the public Dispose method and the Finalize method. Dispose invokes the protected Dispose(Boolean) method with the disposing parameter set to true. Finalize invokes Dispose with disposing set to false.

所以我觉得没问题。

Control.Dispose 的 "bonus" 没有记录。

作为一般提示,您不应围绕未记录的行为在未来或什至在所有当前控件实现中保持不变的期望来构建程序。

但是,从Reference Source of Control.Dispose(bool)可以看出:

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

这确实发生在当前的实施中。

但同样,这不是记录在案的行为。随心所欲。

你应该调用 Dispose() 吗?

每当您看到任何实现 System.IDisposable 的 class 时,您应该假设 class 的设计者认为 class 可能拥有一些稀缺资源。

您没有义务为这些 class 的对象调用 Dispose()。如果你不这样做,终结器会。但是,如果您不调用 Dispose(),稀缺资源的保留时间会超过所需时间,可能会导致资源不足。

确实如此,在将 null 分配给您的控件之前,您应该调用 Control.Dispose()。

是否应该在处理控件之前从控件集合中删除控件?

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

但是,根据您的实施,您确定添加控件的 ControlCollection 不是 System.Windows.Forms.Control.ControlCollection 的子class,并且行为略有不同吗?毕竟: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;