使用 LINQ 为 ControlCollection 中的每个控件删除 DatagridView 中的第一列

Use LINQ to remove the first column in a DatagGridView for each control in a ControlCollection

所以,非 LINQ 方式应该是这样的:

foreach(Control cont in panel1.Controls)
{
    if (cont is DataGridView)
    {
        var grid = cont as DataGridView;
        grid.Columns.RemoveAt(0);
    }
}

我试过在 Linq 中这样做。它更多的是为了学习经验,而不是专门以最好的方式去做。无论如何,这是我目前所处的位置,但它显然不起作用。

panel1.Controls = panel1.Controls
                        .AsParallel()
                        .OfType<DataGridView>()
                        .Select(grid => grid.Columns
                                            .OfType<DataGridViewColumn>()
                                            .Skip(1));

那么可以做些什么来修改linq查询呢?

您提出的解决方案无缘无故地使用了 AsParallel(),并且未能真正删除列。

LINQ 真正用于查询事物,而不是修改它们。为什么要在这里使用 LINQ 解决方案?您已有的循环有什么问题?

可以编写一个 LINQ 表达式来执行您想要的操作,但该表达式要么需要您编写一个显式的 foreach 循环,要么将枚举具体化为一个实际对象,只是为了获得要执行的表达式。该表达式还需要 return 一些值,以保留 LINQ 的查询语义,即使您的操作本身并不涉及 return 值。

例如,您可以这样写:

panel1.Controls.OfType<DataGridView>().Select(
    grid => { grid.Columns.RemoveAt(0); return null; }).ToList();

但我觉得这段代码很难看。它正在创建一个您永远不会使用的全新 List<T> 对象,其中填充了一堆 null 值。

如果你想清理你的原始代码,我会做类似下面的事情:

foreach (DataGridView grid in panel1.Controls.OfType<DataGridView>())
{
    grid.Columns.RemoveAt(0);
}

在那里,您仅将 LINQ 用于算法的 查询 部分,而对其余部分坚持使用传统的命令式语义。