46

我有一个关于订单的问题IEnumerable

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

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

现在,假设需要对已排序的集合进行操作。在这种情况下可以使用 IEnumerable 还是尝试其他IList具有索引支持的方法(即)更好?

换句话说:合同是否对IEnumerable一般订单做出任何保证?

因此,IEnumerable对于保证排序的通用接口来说,这不是一个适当的方法。新的问题是什么接口或类应该用于具有顺序的不可变集合?ReadonlyCollection? IList? 它们都包含Add()方法(甚至在前一个中没有实现)。

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

我知道 LINQ First(),但如果IEnumerable不说它的顺序,这个扩展是非常没用的。

4

4 回答 4

43

IEnumerable/IEnumerable<T>不保证排序,但使用的实现IEnumerable/IEnumerable<T>可能会或可能不会保证排序。

例如,如果您 enumerate List<T>,则保证顺序,但如果您 enumerateHashSet<T>则不提供此类保证,但两者都将使用IEnumerable<T>接口枚举。

于 2012-05-02T08:10:12.030 回答
13

实施细节。IEnumerable 将枚举该项目 - 如何实施取决于实施。大多数列表等按照它们的自然顺序运行(索引 0 向上等)。

IEnumerable 的合同在一般情况下能保证我们的一些订单吗?

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

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

不,不是,因为你可能有内在的秩序。您以 SQL 为例 - 结果是一个 IEnumerable,但如果我之前强制执行了排序(通过使用 OrderBy()),那么 IEnumerable 是根据 LINQ 的定义进行排序的。AsEnumerable().First() 让我得到订单的第一个项目。

于 2012-05-02T08:09:58.430 回答
6

也许您正在寻找IOrderedEnumerable接口?它由扩展方法返回,例如OrderBy()并允许使用ThenBy().

于 2012-05-02T08:12:35.213 回答
4

您混合了两点:枚举和排序。

当您枚举 IEnumerable 时,您不应该关心顺序。您使用接口,它的实现应该关心顺序。

例如:

void Enumerate(IEnumerable sequence)
{
    // loop
}

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

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

于 2012-05-02T08:10:42.487 回答