为什么List<T>没有实现IOrderedEnumerable<T>接口?

13
我希望使用有序的枚举,并将接口用作返回类型,而不是具体类型。我需要返回一组有序的对象。但是,在使用IList实现时,我不能返回IOrderedEnumerable,因为IList不继承IOrderedEnumerable。 在下面的示例中,我有一个视图模型,其中包含一组系列的存储库,实现为系列对象的List,由于它们位于List中,因此已排序。在访问器方法中,我想返回过滤后的系列集,仅返回特定类型的系列对象,同时保留过滤元素中的原始顺序。
/// <summary>
/// Represents the view model for this module.
/// </summary>
public class ViewModel : AbstractViewModel
{
    /// <summary>
    /// Gets the series repository.
    /// </summary>
    /// <value>The series repository.</value>
    public IList<ISeries> SeriesRepository { get; private set; }

    //...
}

//8<-----------------------------

    /// <summary>
    /// Gets the series of the specified type.
    /// </summary>
    public IOrderedEnumerable<T> Series<T>() where T : ISeries
    {
        return ViewModel.SeriesRepository.OfType<T>(); //compiler ERROR
    }

编译器告诉我:
Error   14  Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<T>' to 'System.Linq.IOrderedEnumerable<T>'. An explicit conversion exists (are you missing a cast?) ...

我该如何支持这种情况?为什么“List”没有实现“IOrderedEnumerable”?
编辑:澄清我的意图:即使没有显式地指定键,我只是想在接口级别声明我的仓库有一个顺序。 因此,“.ThenBy”等不应添加新的排序,因为已经有一个排序——我的唯一一个排序。:-)。我知道,这样做会忽略“ThenBy”的意图。
2个回答

17

如何才能让 List<T> 实现 IOrderedEnumerable<T> 接口?那么它必须提供一种创建随后排序的方式...这是什么意思呢?

考虑以下内容:

var names = new List<string> { "Jon", "Holly", "Ash", "Robin", "William" };
var ordered = names.ThenBy(x => x.Length);
那甚至是什么意思?没有“主要”排序顺序(如果我使用了names.OrderBy(x => x),就会有这样的顺序),因此不可能强加一个“次要”的排序顺序。我建议你尝试基于List<T>创建自己的IOrderedEnumerable<T>实现 - 当你尝试实现CreateOrderedEnumerable方法时,我认为你会明白它为什么不合适。你可能会发现我在Edulinq博客上关于IOrderedEnumerable<T>的文章有用。

.ThenBy 只应该添加无次要顺序,它应该只返回原始序列。我发现这种方法忽略了它的本意。 - Marcel
2
@Marcel:确切地说 - 你只是不能以有意义的方式实现它。这就是为什么它没有被实现的原因。 - Jon Skeet
8
我会说,List<T> 是按照其中项的索引排序的。因此,ThenBy 不会改变任何内容,因为没有等于原始排序定义的情况。 - Matthijs Wessels
1
该死,我花了一段时间才搞明白这个问题,但现在是正确的。问题在于List是任意排序的(可以说是插入顺序),而IOrderedEnumerable具有定义的排序顺序,就像通过某些排序函数排序一样。也许它应该被称为ISortedEnumerable。 - Yarek T

9

好的,你错了:List<T> 没有按特定键排序。列表中的元素按照它们被添加的顺序排列。这就是为什么 List<T> 没有实现 IOrderedEnumerable<T> 的原因。
请返回以下内容:

ViewModel.SeriesRepository.OfType<T>().OrderBy(<your order predicate>);

11
@Daniel:我认为List<T>是有序的:正如您所说,它们是“按您放置的顺序排列”的。这是一种顺序,但它不是任何有意义地强制实施“次要”排序的顺序。 - Jon Skeet
2
@Jon:我的理解不同。有序枚举是指,始终按照一个键排序的枚举,与元素插入列表的顺序无关。 - Daniel Hilgarth
3
作为原帖作者,我想强调“我放置它们的顺序”确实是我需要的顺序,即使没有明确的关键字。在这个例子中,存储库的顺序将是有意创建的。 - Marcel
1
@Marcel:那么你期望调用ThenBy的结果是什么?这是你仍然没有澄清的部分。 - Jon Skeet
3
IOrderedEnumerable<T> 被要求按特定键排序的规定在哪里写明了? - Matthijs Wessels
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接