我对IEnumerable
中的订单有疑问。
据我所知,迭代IEnumerable是伪代码可以用以下方式编写:
while (enumerable.HasNext())
{
object obj = enumerable.Current;
...
}
现在,假设一个人需要在排序集合上运行。可以在这种情况下使用IEnumerable,还是尝试使用索引支持的其他方法(即IList
)更好?
换句话说:IEnumerable
的合同是否对订单作出任何保证?
因此,IEnumerable
不是保证排序的通用接口的正确含义。新问题是接口或类应该用于带有顺序的不可变集合? ReadonlyCollection
? IList
?它们都包含Add()
方法(即使在前者中也没有实现)。
我自己的想法:IEnumerable
不对订购提供任何保证。正确的实现可以在不同的枚举中以不同的顺序返回相同的元素(考虑SQL查询)
我知道LINQ First()
,但如果IEnumerable
没有说出有关它的排序,那么此扩展程序就没用了。
答案 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);
在方法内部,它仍然是一个具有固定顺序的列表,但是方法不知道特定的接口实现和它的特殊性。