我的控件没有正确处理?

hye*_*ans 5 c# garbage-collection dispose winforms

我有以下方法:

    public static void Disposer(Control.ControlCollection controls)
    {
        foreach (Control c in controls)
        {
            if (c.HasChildren)
                Disposer(c.Controls);

            if ((c is UltraNumericEditor)
                || (c is UltraComboEditor)
                || (c is UltraTextEditor)
                || (c is UltraDateTimeEditor)
                || (c is UltraCheckEditor)
                || (c is UltraGrid)
                || (c is UltraStatusBar))
            {
                c.Dispose();
                var x = c.IsDiposed; // this is true!
            }

        }
    }
Run Code Online (Sandbox Code Playgroud)

然后我打电话给它:

   [STAThread]
    static void Main()
    {
        Test forma = new Test();
        forma.Controls.Add(new UltraStatusBar());
        forma.Controls.Add(new UltraStatusBar());
        forma.Controls.Add(new UltraNumericEditor());
        forma.Controls.Add(new UltraComboEditor());
        forma.Controls.Add(new UltraTextEditor());
        forma.Controls.Add(new UltraTextEditor());
        forma.Controls.Add(new UltraDateTimeEditor());
        forma.Controls.Add(new UltraTimeZoneEditor());
        forma.Controls.Add(new UltraGrid());

        Disposer(forma.Controls);

        foreach (Control control in forma.Controls)
        {
            if (control.IsDisposed)//this is false now!
            {
                Debug.Write(control.Name + " was disposed");
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

我的问题是,为什么在我的Disposer方法中我的控件正在被处理掉,但是当我检查main方法时返回false?顺便说一下,"Test"对象只是一个继承自UserControl的简单类谢谢,问候.

Han*_*ant 6

Control.ControlCollection类中存在一个错误.缺少生成InvalidOperationException的代码,当您在foreach循环中修改集合时,其他集合类会生成InvalidOperationException.

你正在做什么,调用Dispose()从Controls集合中删除一个控件.实际上,您只处理所有其他控件.

处理控件的更好方法是驱动点回家的控件:

while (controls.Count > 0) controls[0].Dispose();
Run Code Online (Sandbox Code Playgroud)

虽然很难不使用向后工作的for()循环.这段代码几乎总是不必要的,Winforms会自动处理控件.并且没有任何需要处理控件的CreateControl()方法尚未被调用.在容器表单调用并完成其Show()方法之前,这种情况不会发生.仅在调用Controls.Remove()或Controls.Clear()方法时自行处理控件.