代码分析CA2000:这段代码好吗?

时间:2011-03-26 15:51:41

标签: winforms c#-4.0 dispose

看看这段代码,我相信它解决了CA2000,但我想确保我不会忽视某些东西。基本上,此代码会根据Control中选择的内容加载新的TreeView。然后会显示Control并且可见/可用,直到选择Node中的另一个TreeView为止。

private void Something(object sender, TreeViewEventArgs e)
{
    ProjectTreeNode node = (e.Node as ProjectTreeNode);

    foreach (Control c in optionsPlaceholderPanel.Controls)
        c.Dispose();

    optionsPlaceholderPanel.Controls.Clear();

    if (node != null)
    {
        //ProjectOptions inherits from Control and is therefore IDisposable
        ProjectOptions options = new ProjectOptions(node.Project);

        ShowOptionsPanel(options);
    }
}

private void ShowOptionsPanel(Control control)
{
    optionsPlaceholderPanel.Controls.Add(control);
    control.Dock = DockStyle.Fill;
}

所以基本上Control始终在范围内,直到加载新的Control代替它。当我这样做时,我正在处理先前加载的Control所以我认为在这种情况下忽略CA2000是安全的。此外,当Form最终关闭并且optionsPlaceholderPanel被处置时,这也会处理子控件,对吗?

1 个答案:

答案 0 :(得分:0)

foreach (Control c in optionsPlaceholderPanel.Controls)
    c.Dispose();

不,这段代码有错误。这本身是由ControlCollection类中的错误触发的。你的foreach循环修改面板的Controls集合。这通常会产生InvalidOperationException,“集合已被修改,枚举操作可能无法执行”,但该类忘记执行此操作。

控件上的Dispose()调用将其从集合中删除。实际上,您只会处置所有其他控件。这应该有副作用,它们在面板上仍然可见。因人而异。修正:

        for (int ix = optionsPlaceholderPanel.Controls.Count - 1; ix >= 0; --ix)
            optionsPlaceholderPanel.Controls[ix].Dispose();

效率较低,但你从来没有看到差异:

        while (optionsPlaceholderPanel.Controls.Count > 0)
             optionsPlaceholderPanel.Controls[0].Dispose();

否则代码没问题,CA2000往往会产生错误警告。