C# 对一组IEnumerables进行Foreach

C# 对一组IEnumerables进行Foreach,c#,foreach,ienumerable,C#,Foreach,Ienumerable,我有3个互斥的IEnumerables要迭代。我想这样做: IEnumerable<Car> redCars = GetRedCars(); IEnumerable<Car> greenCars = GetGreenCars(); IEnumerable<Car> blueCars = GetBlueCars(); foreach(Car c in (redCars + greenCars + blueCars)) { c.DoSomething()

我有3个互斥的IEnumerables要迭代。我想这样做:

IEnumerable<Car> redCars = GetRedCars();
IEnumerable<Car> greenCars = GetGreenCars();
IEnumerable<Car> blueCars = GetBlueCars();

foreach(Car c in (redCars + greenCars + blueCars)) {
    c.DoSomething();
}

...
IEnumerable redCars=GetRedCars();
IEnumerable greenCars=GetGreenCars();
IEnumerable blueCars=GetBlueCars();
foreach(c车进站(红色车+绿色车+蓝色车)){
c、 DoSomething();
}
...
我能想到的最好办法是:

...
List<Car> allCars = new List();
allCars.AddRange(redCars);
allCars.AddRange(greenCars);
allCars.AddRange(blueCars);
foreach(car in allCars) {
    ...
}
...
。。。
列出所有车辆=新列表();
allCars.AddRange(红色汽车);
allCars.AddRange(绿色汽车);
allCars.AddRange(blueCars);
foreach(所有车辆中的车辆){
...
}
...
有没有更简洁的方法?似乎组合IEnumberable应该很简单。

使用LINQ Union方法

foreach(Car c in redCars.Union(greenCars).Union(blueCars))
{
    c.DoSomething();
}
林克:

foreach(car in redCars.Concat(greenCars).Concat(blueCars)) {
    //...
}

就信息而言,
Union
Concat
之间的区别在于
Union
将做额外的工作来保证唯一性;因此,如果您不希望重复(或者:不介意重复),那么
Concat
会更快。

是否有理由在一个循环中执行此操作?如果是这样,第二种方法可能是最好的。没有什么比第一种方法更有效的了


除非有压倒性的需要在一个循环中完成,否则我会在三个循环中完成,这样会更省时。

如其他答案中所述,Union会做额外的工作来消除重复,Concat只是将序列连接起来。然而,正如我在上面的评论中所指出的,深度嵌套的concat会带来性能代价。您也可以考虑使用一个StULTOME来平移一组迭代器:

var carLists = new[]{GetRedCars(), GetGreenCars(), GetBlueCars()};
var allCars = from carList in carLists
              from car in carList 
              select car;
foreach(var c in allCars) { ... }

您可能会发现,如果您发现您实际上有三个以上的列表需要迭代,那么这种方法会更灵活。

如果您确实需要在一个循环中执行此操作,我会选择LINQ。我没有想到这一点。但这难道不是很昂贵,因为它必须将它们全部进行比较吗?特别是因为这三个组是相互排斥的。就信息而言,
Union
将比这里的
Concat
更昂贵,并且很可能产生与
AddRange
方法(本质上是
Concat
)不同的结果。@sdr,如果这些收藏不共享任何元素,最好使用Marc Garvell提到的Concat。。。我从Concat开始,然后去了Union,然后决定我不能决定使用哪个,所以我删除了我的答案。不管怎样,我更喜欢你解释这种差异+1正是我想要的。谢谢@sdr:注意这里有一个时间/空间权衡。假设你不是三个而是二十个这样的列表,每个列表有一万个元素。您的方法(将它们连接到一个大列表中)将占用大约20 x 10K的额外引用,并占用20 x 10K的引用复制操作。另一方面,执行20个朴素的concat不需要额外的引用,但是嵌套的concat有一个基于嵌套深度的复制负担,因此将有10 x 11 x 10K=110K个拷贝,而不是20K个拷贝。有关详细信息,请参见。@Eric-因此,在假设的未来版本的C#中,是否有希望获得一个
收益率foreach
构造?我认为“更省时”是一个很大的要求。还要注意,创建一个列表(包括分配、复制等)也有开销。还有很多东西会像第一种方式一样工作。@Scott,如果他用同样的方式处理每辆车,为什么他会想要不止一个回路?那只是多余的代码。