将嵌套的foreach转换为lambda表达式

时间:2011-03-30 11:37:58

标签: c# lambda

我想转换嵌套的foreach

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));
          }
    }

这样的事情

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

3 个答案:

答案 0 :(得分:1)

您可以安装ReSharper 5的试用版,因为它有一个重构选项,可以将foreach循环转换为LINQ表达式(如果可能)。

http://blogs.jetbrains.com/dotnet/2009/12/resharper-50-preview-loops-2-linq/

答案 1 :(得分: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,所以我就在这里停下来。

答案 2 :(得分: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))
    });