是否可以使用LINQ执行基于集合的属性分配?

时间:2010-10-29 04:16:30

标签: linq

我正在尝试测试LINQ能走多远。我想要实现的是具有单个表达式而不是循环的对象列表上的属性赋值。我想获取listA中的所有项目并更新IsMatched属性,但只有在listB中有相应项目(这是另一种类型)的情况下,这可能吗?

示例代码:

public struct A { public int x; public bool IsMatched;}
public struct B {public int x;}

static void Main(string[] args)
{
  List<A> listA = new List<A>(); 
  List<B> listb = new List<B>();
  listA.Add(new A() { x=1}); 
  listA.Add(new A() { x=2}); 
  listA.Add(new A() { x=3});

  listb.Add(new B() { x=2}); 
  listb.Add(new B() { x=3});

  listA = listA.SelectMany(fb => listb, (fb, j) => new {a=fb, b=j})
        .Where (anon => anon.b.x == anon.a.x).Select(anon => new A() {x=anon.a.x, IsMatched=true})
        .ToList(); // this does not do what I want.

}

我尝试过使用SelectMany,但这只返回匹配的项目,或者我不想要的笛卡尔产品。

1 个答案:

答案 0 :(得分:5)

LINQ不是为了引起副作用而设计的。在这种情况下,修改集合中的项目。只需创建查询以选择要修改的项目,然后根据需要循环修改项目。

var query = from a in listA
            join b in listB on a.x equals b.x
            select a;
foreach (var a in query)
    a.IsMatched = true;

然而你可以作弊并制定一个lambda来引起副作用。然后使用它作为聚合方法。但是你不应该在实践中这样做。

(from a in listA
 join b in listB on a.x equals b.x
 let modify = new Func<A,A>(m => { m.IsMatched = true; return m; })
 select modify(a)).ToArray();