2010-10-29 17 views
1

我想测试LINQ可以走多远。我试图实现的是一个单一表达式而不是循环的对象列表上的属性分配。我想采取listA中的所有项目并更新IsMatched属性,但只有在listB中有相应项目(这是不同类型)时,这可能吗?是否可以使用LINQ执行基于集合的属性分配?

示例代码:

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

上的副作用的问题,见http://blogs.msdn.com/b/ericlippert/archive/2009/05/18/foreach-vs-foreach.aspx – 2010-10-29 04:49:16

回答

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(); 
+0

@Jeff米 - 谢谢 - 显然可以在匿名方法检查[this]内完成任务(http://stackoverflow.com/questions/807797/linq-select-an-object-and-change-some-properties-without-creating-a-新对象)出来,只是自己读。这至少让我一半。 – James 2010-10-29 04:46:13

+0

@詹姆斯:对,就像我在第二个例子中所展示的那样。 ;) – 2010-10-29 04:49:33

+0

@Jeff M - 对不起,下次我需要仔细阅读;)。为什么这样做被认为是一种不好的做法? – James 2010-10-29 04:56:04

相关问题