C# 在C语言中优化Linq#

C# 在C语言中优化Linq#,c#,linq,C#,Linq,我有一个列列表,其中我需要为除两列以外的所有列指定Isselected为true。(Bug和特性)。我已经使用了下面的代码来实现它,并且工作得很好,但是有没有快速或简单的方法来实现相同的功能 DisplayColumns.ToList().ForEach(a => a.IsSelected = true); DisplayColumns.ToList().Where(a => a.ColumnName == "Bug" || a.ColumnName == "Feature")

我有一个列列表,其中我需要为除两列以外的所有列指定Isselected为true。(Bug和特性)。我已经使用了下面的代码来实现它,并且工作得很好,但是有没有快速或简单的方法来实现相同的功能

DisplayColumns.ToList().ForEach(a => a.IsSelected = true);
DisplayColumns.ToList().Where(a => a.ColumnName == "Bug" ||    a.ColumnName == "Feature").ToList().ForEach(a => a.IsSelected = false);

提前感谢

当然,您可以立即将
指定为选中的

DisplayColumns.ToList().ForEach(a => a.IsSelected = !(a.ColumnName == "Bug" || a.ColumnName == "Feature"));

如果
DisplayColumns
不是匿名类型的投影(在这种情况下,属性不可重新分配),则可以在集合的单次迭代中更改标志

您还可以使用
Contains
来简化比较。在课堂范围内:

private static readonly string[] _searches = new [] {"Bug", "Feature"}
在您的方法中:

DisplayColumns
.ToList() // For List.ForEach, although not @JonSkeet's caveat re mutating in Linq
.ForEach(a => a.IsSelected = !_searches.Contains(a.ColumnName));
编辑

正如其他人所提到的,创建一个新列表仅仅是为了访问(原始)集合中的更改对象是浪费的,并且在值类型集合上的更改将丢失。相反,使用
foreach
(甚至是
for
)迭代原始集合

我已经使用了下面的代码来实现它,并且工作得很好,但是有没有快速或简单的方法来实现相同的功能

DisplayColumns.ToList().ForEach(a => a.IsSelected = true);
DisplayColumns.ToList().Where(a => a.ColumnName == "Bug" ||    a.ColumnName == "Feature").ToList().ForEach(a => a.IsSelected = false);
在我看来,有一种更干净的方法来实现这一点——根本不要使用lambdas等:

foreach (var item in DisplayColumns)
{
    item.IsSelected = item.ColumnName != "Bug" && item.ColumnName != "Feature";
}
您可以一次性做出决定-如果列名是“bug”或“feature”,则为
false
;它是
真的
否则。当C语言有一个非常好的
ForEach
循环结构时,您不需要调用
ToList
并使用
ForEach
,以便使用集合中的每个项执行一些代码

我喜欢LINQ——它太棒了——但它的最佳点是质疑(因此是Q),而不是操纵。在这种情况下,只有
ToList
部分是LINQ-
列表的偶数部分。ForEach
是在LINQ之前在.NET 2.0中引入的。

可能是:

tmp = DisplayColumns.ToList();
var res = tmp.Except(tmp.Where(a => a.ColumnName == "Bug" ||    a.ColumnName == "Feature"));

foreach(var x in res) x.IsSeleceted = true;

首先,当从IEnumerable创建集合时,只需调用ToList()一次。 在每个操作员之后执行此操作既昂贵又冗余

第二,改变你的状况。除拖缆外,其余均为真

     DisplayColumns.Where(a => a.ColumnName != "Bug" && a.ColumnName != "Feature").ForEach(a => a.IsSelected = true).ToList();
编辑:

很抱歉,我喜欢约翰的部分答案,因为这可能是重复发生的事情,或者IsSelected可能是可空的,不管怎样,让我们尽可能保持它的一般性

我也喜欢斯图尔特的方法,对这个系列(我也想过,但不想混淆。所以让我们把最好的世界给你)

当使用linq时,我们实际上是在构建一个表达式树,在它的末尾我们可以选择具体化为一个集合

for_搜索可能会改变,每次我们具体化该表达式时,我们都会使用该集合中当前的值进行搜索,从而使代码更加通用

 private static readonly string[] _searches = new [] {"Bug", "Feature"}

 DisplayColumns.ForEach(a => a.IsSelected =  !_searchs.Contains(a.ColumnName)).ToList();
我假设ForEach是不使用ForEach的IEnumerable类型的扩展方法

    DisplayColumns
    .Select(s=> {
                    s.IsSelected = (s.ColumnName == "Bug" && s.ColumnName == "Feature");
                    return s;   
                });

好的,我建议您使用简单的foreach或for循环。您将在两个查询中遍历这里的集合两次。相反,使用foreach循环实现它,它只保证单循环迭代。首先,您不需要调用ToList()在他们身上使用linq,代价高昂而且是多余的。where子句是错误的-
ToList
在第二行的末尾是错误的,我猜你错过了一个结尾(
在那里…谢谢-我先做了一点散列@Jehof我相信OP只是想根据每个对象中其他属性的值来改变一个标志。我使用了这段代码,因为它看起来很简单,感谢您的解释。:)我相信OP使用了
ToList()
来获取对的访问权限,即他自己编写的扩展方法,如果是这样的话,它应该是IEnumerable而不是List类型的扩展方法。它已经存在了很长一段时间,但正如其他人所说,使用它对集合执行副作用的更改是不受欢迎的。