2011-03-30 42 views
1

我想转换为嵌套的foreach到lambda表达式

foreach (Tuple<int, string, Guid> s in services) 
    { 
     foreach (BEPartnership p in partnership) 
     {                  
      p.Partner.Services = new List<Tuple<int, string>>(); 
      if (s.Item3 == p.Partner.Id) 
       p.Partner.Services.Add(new Tuple<int, string>(s.Item1, s.Item2)); 
      } 
    } 

转换嵌套的foreach对这样的事情

services.SelectMany( 
s=>partnership.Select(
p=>new {partnerId = p.Partner.Id, servicePartnerId = s.Item3}) 
    .Where(x=>x.partnerId == x.servicePartnerId) 
    .ToList() 
    .ForEach(//....)) 
+0

这样有什么不好? – gideon 2011-03-30 11:45:11

+2

值得注意的是,仅仅因为使用LINQ可以表达的东西并不意味着它是必要的。首先考虑可读性。 – 2011-03-30 11:53:51

回答

1

你是不是真的做一个查询在这里,所以LINQ可能是错误的做法。
但是,你可以改变你的两个foreach循环到这一点:

foreach (var p in partnership) 
    p.Partner.Services = new List<Tuple<int, string>>(); 

foreach (var s in services) 
{ 
    partnership.Where(p => s.Item3 == p.Partner.Id).ToList().ForEach(
     p => p.Partner.Services.Add(new Tuple<int, string>(s.Item1, s.Item2))); 
} 

这是否真的提供任何好处?我对此表示怀疑。

进一步与SelectMany和东西感觉就像强奸LINQ,所以我停在这里。

+0

我是否将foreach(var s in services){...}转换为lambda? – Alexandre 2011-03-30 13:02:02

+0

当然,你可以做到这一点,但你的代码将不再可读imho。 – 2011-03-30 13:04:53

0

首先,我总是创造一个静态实用/扩展类来定义这些方法:

public static void AddAll<T>(this ICollection<T> c, IEnumerable<T> items) 
{ 
    items.ForEach(item => c.Add(item)); 
} 

public static void AddAll<T1, T2>(this ICollection<T1> c, IEnumerable<T2> items, Func<T2, T1> converter) 
{ 
    c.AddAll(items.Select(converter)); 
} 

public static void ForEach<T>(this IEnumerable<T> e, Action<T> action) 
{ 
    foreach (T item in e) 
     action.Invoke(item); 
} 

现在,所有你需要的是这样的:

partnership.ForEach(p => 
    { 
     p.Partner.Services = new List<Tuple<int, string>>(); 
     p.Partner.Services.AddAll(from s in services 
       where s.Item3 == p.Partner.Id 
       select Tuple.Create(s.Item1, s.Item2)) 
    });