2013-01-03 324 views
8

我有列表,I;只需要使用LINQ/LAMBDA选择一定的标准,基地Lists.ForEach用条件选择使用LINQ/LAMBDA

我的代码是

Lists.ForEach(x => x.IsAnimal == false { /* Do Something */ }); 

我收到错误“只有分配,电话,递增,递减和新对象表达式可以用作声明”在这部分x.IsAnimal == false

我知道我们可以用一个for循环很容易实现这一点,但我想使用LINQ/LAMBDA

回答

18

了解更多只要使用ToList使用的ForEach

之前
Lists.Where(x => !x.IsAnimal).ToList().ForEach(...) 
+0

+1对于那些光荣的事物替换'!' =) – Coops

+1

['Enumerable.Where'](http://msdn.microsoft.com/zh-cn/library/bb534803.aspx)的结果是'IEnumerable '。至少在BCL中,'IEnumerable '没有'ForEach'扩展方法,所以你的代码不会被编译。 –

+0

哪里不会返回'List '。 'ToList()'丢失:'Lists.Where(x =>!x.IsAnimal).ToList()。ForEach(' – nemesv

4

请在syntax of lambda expressions读了:一个lambda表达式表示的方法; =>之前的部分是参数列表,之后的部分是返回结果的单个表达式或方法体。

您可以在方法体中添加限制:

Lists.ForEach(x => { 
        if (!x.IsAnimal) { 
         // do something 
        } 
       }); 
+3

+1因为没有建立一个新的列表只是为了调用ForEach – Rawling

3

应该是这样的:

things.Where(x => !x.IsAnimal).ToList().ForEach(x => { // do something }); 

我可以看到人们都在抱怨不得不建立新的列表中使用的ForEach。你可以做同样的事情选择和坚持的IEnumerable:

things.Where(x => !x.IsAnimal).Select(x => 
{ 
    // do something with it 
    return x; // or transform into something else. 
}); 
16

这是不工作,因为你不能有false{}结构。

Lists.ForEach(x => { 
        if(x.IsAnimal){ 
         //Do Something 
        } 
      }); 
+4

+1没有建立一个新的'List'只是为了调用'ForEach' ... – Rawling

0

请记住,有 lists.foreach和正常的foreach之间的差异。每个“普通”使用枚举器,因此更改迭代列表是非法的。 lists.foreach()不使用枚举器(如果我不错误地说它在后台使用索引器)可以随时更改数组中的项目。

希望这有助于

+0

是的!在大多数情况下,只是使用' foreach“,它几乎感觉像是一个错误,.NET 2.0的作者决定包含List <>。ForEach(Action <>)' –

-2

尝试这样的代码:

class A { 
    public bool IsAnimal { get; set; } 
    public bool Found { get; set; } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     List<A> lst = new List<A>(); 

     lst.Add(new A() { IsAnimal = false, Found = false }); 
     lst.Add(new A() { IsAnimal = true, Found = false }); 
     lst.Add(new A() { IsAnimal = true, Found = false }); 
     lst.Add(new A() { IsAnimal = false, Found = false }); 

     // Here you first iterate to find only items with (IsAnimal == false) 
     // then from IEnumerable we need to get a List of items subset 
     // Last action is to execute ForEach on the subset where you can put your actions... 
     lst.Where(x => x.IsAnimal == false).ToList().ForEach(y => y.Found = true); 
    } 
} 
+0

Brotip,不需要'== false'和'== true' 。可以分别为'!x.IsAnimal'和'y.Found'。 – Arran

+0

@Arran感谢您的评论,这只是为了清晰的代码。 –

0

如果你想使用 “的ForEach” 对不同类型的集合,你应该写为IEnumerable的扩展:

public static class IEnumerableExtension 
{ 
    public static void ForEach<T>(this IEnumerable<T> data, Action<T> action) 
    { 
     foreach (T d in data) 
     { 
      action(d); 
     } 
    } 
} 

使用此扩展程序,您可以在使用ForEach之前进行过滤,并且不必使用已过滤的项目形成新的列表:

lists.Where(x => !x.IsAnimal).ForEach(/* Do Something */ ); 

我prefere标准版:

foreach (var x in lists.Where(x => !x.IsAnimal)) { /* Do Something */ } 

不是很长,显然与副作用的循环。