IEnumerable和订单

时间:2012-05-02 08:04:49

标签: c# .net collections ienumerable

我对IEnumerable中的订单有疑问。

据我所知,迭代IEnumerable是伪代码可以用以下方式编写:

while (enumerable.HasNext())
{
    object obj = enumerable.Current;
    ...
}

现在,假设一个人需要在排序集合上运行。可以在这种情况下使用IEnumerable,还是尝试使用索引支持的其他方法(即IList)更好?

换句话说:IEnumerable的合同是否对订单作出任何保证?

因此,IEnumerable不是保证排序的通用接口的正确含义。新问题是接口或类应该用于带有顺序的不可变集合? ReadonlyCollectionIList?它们都包含Add()方法(即使在前者中也没有实现)。

我自己的想法:IEnumerable不对订购提供任何保证。正确的实现可以在不同的枚举中以不同的顺序返回相同的元素(考虑SQL查询)

我知道LINQ First(),但如果IEnumerable没有说出有关它的排序,那么此扩展程序就没用了。

4 个答案:

答案 0 :(得分:30)

IEnumerable/IEnumerable<T>不保证订购,但使用IEnumerable/IEnumerable<T>的实施可能会或可能不会保证订购。

例如,如果您枚举List<T>,则会保证订单,但如果您枚举HashSet<T>,则不会提供此类保证,但两者都将使用IEnumerable<T>界面进行枚举。

答案 1 :(得分:12)

实施细节。 IEnumerable将枚举该项 - 实现方式取决于实现。 MOST列表等按其自然顺序运行(索引0向上等)。

  

IEnumerable的合同在一般情况下是否保证了我们的订单?

不,它只保证枚举(每个项目一次等)。 IEnumerable没有保证订单,因为它也可用于无序项目。

  

我知道LINQ First(),但如果IEnumerable没有说出它的顺序,那么这个扩展是没用的。

不,不是,因为你可能有内在的秩序。您给SQL作为示例 - 结果是IEnumerable,但如果我之前已经强制执行排序(通过使用OrderBy()),则按照LINQ的定义对IEnumerable进行排序。 AsEnumerable()。First()然后按顺序获取第一个项目。

答案 2 :(得分:6)

也许您正在寻找IOrderedEnumerable界面?它由OrderBy()等扩展方法返回,并允许随后使用ThenBy()进行排序。

答案 3 :(得分:4)

你混合两点:枚举和排序。

当您枚举IEnumerable时,您不应该关心订单。您使用界面,其实现应该关心顺序。

例如:

void Enumerate(IEnumerable sequence)
{
    // loop
}

SortedList<T> sortedList = ...
Enumerate (sortedList);

在方法内部,它仍然是一个具有固定顺序的列表,但是方法不知道特定的接口实现和它的特殊性。