从以下两种方式来枚举一个集合,如果一个优先于另一个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;
答案 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
来优化其实现。
一个合理的经验法则是:当您正在访问项目以产生副作用时,您应该在转换时使用for
或foreach
(投影) )一个序列到另一个序列你应该使用LINQ(Select,Where等等)。使用LINQ强调隐藏机制的结果,而循环强调机制。
答案 1 :(得分:3)
在你提到的那些中,首先是首选。第二个会做更多的事情,包括转换到一个列表并检查类型,最后无论如何都要做一个foreach。
当然还有其他方法可以迭代,但它们依赖于集合。对于IList
实现和数组,您可以使用普通for
循环并使用myitem[i]
为项目编制索引。
但是没有理由不使用foreach,因为它适用于所有系列,并且AFAIK在性能方面始终是最佳选择。通过最优,我的意思是在算法复杂度/ big-o
方面 编辑以回复您的问题编辑
通常,您应该使用提供最佳可读性的枚举方案(不会严重影响性能)。在您的示例中,您想要查看列表是否包含特定类型的任何元素,那么我将使用LINQ路由(collection.OfType...
)。它清楚地表达了意图,并且几乎可以用英语阅读文本并获得含义:“在我的收藏中,获取X类型的元素并告诉我它是否存在。”
答案 2 :(得分:1)
有Parallel.ForEach:
答案 3 :(得分:0)
显然,转换集合的不将比转换它更快。
答案 4 :(得分:0)
我更喜欢第一种方法,因为您不会像转换为列表那样丢失基础枚举器。对于大多数收藏品而言,没有太大区别,但如果它是一个大型集合或通过产生结果计算的集合,那么它可能很重要。
答案 5 :(得分:0)
对于某些类型的集合(如List(Of T)),通过经典foreach
枚举的速度要快得多。这是因为C#中的foreach
构造不直接使用IEnumerator和IEnumerable。
它调用GetEnumerator()方法然后调用MoveNext()并返回Current on对象。由于List返回ListEnumerator结构,当直接调用时哪些方法更快,否则通过IEnumerator接口调用。