枚举集合的不同方法

时间:2010-12-29 19:35:26

标签: c# collections c#-4.0

从以下两种方式来枚举一个集合,如果一个优先于另一个OR,则在性能方面都是相同的(即,因为ToList()转换涉及第二种方法)

foreach(SomeType st in Collection)
{
   //Do something
}


Collection.OfType<SomeType>.ToList().ForEach()

还有其他方法(除了使用relection)吗?

修改

这种情况怎么样?

class SomeType : IMyType
{
}

class OtherType : IMyType
{
}

class SomeCollection<T> : IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable
{
}

考虑到MyTypes是类型SomeCollection<IMyType>的类中的属性,下面的2接近相同?

foreach(IMyType mt in MyTypes) 
{   
  if(IMyType is SomeType)
  return; 
}

OR

if(MyTypes.OfType<SomeType>.Any())
    return;

6 个答案:

答案 0 :(得分:3)

当然,对于可索引的集合,您可以使用经典的for循环:

for( int i = 0; i < collection.Count; i++ )
{
    collection[i] ... // do something with the item
}

你也可以直接访问IEnumerator对象(foreach是语法糖):

using( IEnumerator<YourType> e = collection.GetEnumerator() )
{
    while( e.MoveNext() )
    {
        // do something with the item
        e.Current ...
    }
}

枚举集合的所有不同方法在某些特定情况下都很有用 - 但在使用哪种模式的情况下它是非常有用的。

例如,直接使用IEnumerator对象非常有用,您可以精确控制如何以及何时增加和访问迭代器。许多LINQ运算符在内部使用IEnumerator来优化其实现。

一个合理的经验法则是:当您正在访问项目以产生副作用时,您应该在转换时使用forforeach(投影) )一个序列到另一个序列你应该使用LINQ(Select,Where等等)。使用LINQ强调隐藏机制的结果,而循环强调机制。

答案 1 :(得分:3)

在你提到的那些中,首先是首选。第二个会做更多的事情,包括转换到一个列表并检查类型,最后无论如何都要做一个foreach。

当然还有其他方法可以迭代,但它们依赖于集合。对于IList实现和数组,您可以使用普通for循环并使用myitem[i]为项目编制索引。

但是没有理由不使用foreach,因为它适用于所有系列,并且AFAIK在性能方面始终是最佳选择。通过最优,我的意思是在算法复杂度/ big-o

方面

编辑以回复您的问题编辑 通常,您应该使用提供最佳可读性的枚举方案(不会严重影响性能)。在您的示例中,您想要查看列表是否包含特定类型的任何元素,那么我将使用LINQ路由(collection.OfType...)。它清楚地表达了意图,并且几乎可以用英语阅读文本并获得含义:“在我的收藏中,获取X类型的元素并告诉我它是否存在。”

答案 2 :(得分:1)

答案 3 :(得分:0)

显然,转换集合的将比转换它更快。

答案 4 :(得分:0)

我更喜欢第一种方法,因为您不会像转换为列表那样丢失基础枚举器。对于大多数收藏品而言,没有太大区别,但如果它是一个大型集合或通过产生结果计算的集合,那么它可能很重要。

答案 5 :(得分:0)

对于某些类型的集合(如List(Of T)),通过经典foreach枚举的速度要快得多。这是因为C#中的foreach构造不直接使用IEnumerator和IEnumerable。

它调用GetEnumerator()方法然后调用MoveNext()并返回Current on对象。由于List返回ListEnumerator结构,当直接调用时哪些方法更快,否则通过IEnumerator接口调用。