如何使用LINQ简化2 foreach?

时间:2012-03-08 16:41:09

标签: c# linq c#-4.0

我怎样才能以更易读的方式做到这一点?

 foreach (var actual in actualPositions)
 {
     foreach (var projection in projections)
     {
         var position        = Create(book, actual, projection);
         position.TargetNett = projection.DailyProjectedNet.ToString();
         yield return position;
     }
 }

5 个答案:

答案 0 :(得分:12)

你想要简化吗?为什么?它简单易读,易懂。你可以提出各种各样的gobbledygook 更难来阅读,但肯定看起来更酷。不要!抵制幻想的冲动。

答案 1 :(得分:2)

return 
  from actual in actualProjections
  from projection in projections
  select Create(book, actual, projection)
          .With_TargetNett(projection.DailyProjectedNet.ToString());

其中With_TargetNett是扩展名

static Position With_TargetNett(this Position position, string targetNett)
{
 position.TargetNett = targetNett;
 return position;
}

答案 2 :(得分:2)

您可以执行的一个选项是实现自己的交叉连接,并对其进行枚举。然而,它仍然不是很漂亮:

actualPositions.SelectMany(actual => projections.Select(project => new { actual, project }))

但是,如果您使用的是.NET 4.0或更高版本,则可以使用元组(默认)或您自己的自定义选择器实现交叉连接扩展方法:

public static IEnumerable<Tuple<T1, T2>> CrossJoin<T1, T2>(this IEnumerable<T1> source, IEnumerable<T2> toJoin)
{
    return source.CrossJoin(toJoin, Tuple.Create<T1, T2>);
}

public static IEnumerable<T3> CrossJoin<T1, T2, T3>(this IEnumerable<T1> source, IEnumerable<T2> toJoin, Func<T1, T2, T3> selector)
{
    return source.SelectMany(tFirst => toJoin.Select(tSecond => selector(tFirst, tSecond)));
}

然后这可以更容易使用:

foreach(var pair in actualPositions.CrossJoin(projections))
{
    var position = Create(book, pair.Item1, pair.Item2);
    position.TargetNett = pair.Item2.DailyProjectedNet.ToString();
    yield return position;
}
// OR
return actionPositions.CrossJoin(projections, (actual, project) => { /*Code in foreach loop above here, without the "yield". */ });

答案 3 :(得分:0)

只是为了好玩

return 
 (
  from actual in actualProjections  
  from projection in projections  
  select new {actual, projection}
 ).Select(pair => 
   {
     var position = Create(book, pair.actual, pair.projection);   
     position.TargetNett = pair.projection.DailyProjectedNet.ToString();           
     return position;
   }
 );

答案 4 :(得分:0)

在这种情况下,Linq提供的可读性较低。 您可以使用单独的方法移动第二个foreach语句,然后使用Linq

return from actual in actualPositions
       select GetBookPositionList(actual);

新方法:

private List<BookPosition> GetBookPositionList(ActualPosition actual)
{
  foreach (var projection in projections)
  {
    var position = Create(book, actual, projection);
    position.TargetNett = projection.DailyProjectedNet.ToString();
    yield return position;
  }
}