C#:如何实现 IOrderedEnumerable<T> [英] C#: How to implement IOrderedEnumerable&lt;T&gt;

查看:32
本文介绍了C#:如何实现 IOrderedEnumerable<T>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现一些不同的算法来练习,只是为了看看我到底有多糟糕并变得更好:p

I want to implement some various algorithms for practice, just to see how bad I really am and to get better :p

无论如何,我想我会尝试使用 IEnumerableIOrderedEnumerable 和其他 .Net 集合类型只是为了兼容(这样我以后可以更轻松地使用 write).

Anyways, I thought I would try to use IEnumerable<T> and IOrderedEnumerable<T> and other .Net collection types just to be compatible (so that what I write can be used more easily later).

但除了使用 OrderBy 和 ThenBy 扩展方法之外,我找不到返回 IOrderedEnumerable 实例的方法.所以我想我必须创建自己的类来实现这个接口.但老实说,这个界面对我来说并没有多大意义.可能会,但我不确定.

But I can't find a way to return an instance of IOrderedEnumerable<T> other than using the OrderBy and ThenBy extension methods. So I guess I have to create my own class that implements this interface. But the interface doesn't quite make sense to me to be honest. It might, but I'm not sure.

我创建了一个空类,添加了接口,然后让 ReSharper 为我添加了空实现.它看起来像这样:

I created an empty class, added the interface and then got ReSharper to add empty implementations for me. It looks like this:

class MyOrderedEnumerable<T> : IOrderedEnumerable<T>
{
    /// <summary>
    /// Performs a subsequent ordering on the elements of an <see cref="T:System.Linq.IOrderedEnumerable`1"/> according to a key.
    /// </summary>
    /// <returns>
    /// An <see cref="T:System.Linq.IOrderedEnumerable`1"/> whose elements are sorted according to a key.
    /// </returns>
    /// <param name="keySelector">The <see cref="T:System.Func`2"/> used to extract the key for each element.</param><param name="comparer">The <see cref="T:System.Collections.Generic.IComparer`1"/> used to compare keys for placement in the returned sequence.</param><param name="descending">true to sort the elements in descending order; false to sort the elements in ascending order.</param><typeparam name="TKey">The type of the key produced by <paramref name="keySelector"/>.</typeparam><filterpriority>2</filterpriority>
    public IOrderedEnumerable<T> CreateOrderedEnumerable<TKey>(Func<T, TKey> keySelector, IComparer<TKey> comparer, bool descending)
    {
        throw new NotImplementedException();
    }

    /// <summary>
    /// Returns an enumerator that iterates through the collection.
    /// </summary>
    /// <returns>
    /// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
    /// </returns>
    /// <filterpriority>1</filterpriority>
    public IEnumerator<T> GetEnumerator()
    {
        throw new NotImplementedException();
    }

    /// <summary>
    /// Returns an enumerator that iterates through a collection.
    /// </summary>
    /// <returns>
    /// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection.
    /// </returns>
    /// <filterpriority>2</filterpriority>
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

我不明白的是 CreateOrderedEnumerable 方法.它到底是做什么的?好吧,我想它当然会创建一个有序的可枚举,但是如何呢?排序算法本身应该放在那里吗?它会排序什么?没有项目的集合进入该方法,那么它意味着在哪里订购集合?你会如何使用这个类?它是否意味着在需要对内容进行排序的东西中实现为例如私有帮助类?

What I don't understand is the CreateOrderedEnumerable method. What exactly is it meant to do? Well, I guess it of course would create an ordered enumerable, but how? Is the sorting algorithm itself supposed to go in there? And what will it sort? There is no collection of items going in to that method, so where is it meant to get the collection to order? How would you use the class? Is it meant to be implemented as for example a private helper class inside something that needs to sort stuff?

然后代替 MyOrderedEnumerable: IOrderedEnumerable,你可能有一个 QuickSorter;: IOrderedEnumerable 在其构造函数中获取一个集合并在调用 CreateOrderedEnumerable 方法时对其进行排序......但是如果有人调用 GetEnumerator 会发生什么> 并在调用该方法之前开始枚举?

Then instead of a MyOrderedEnumerable<T> : IOrderedEnumerable<T>, you might have a QuickSorter<T> : IOrderedEnumerable<T> that took a collection in its constructor and sorted it when that CreateOrderedEnumerable method was called... but what would then happen if someone called GetEnumerator and started to enumerate before that method had been called?

哈哈,刚刚发现我前段时间问过类似的问题这里.但这只是关于是否有可能返回一个.所以我想这个问题是对我在那里得到的一个答案的回应 =)

Haha, just discovered I had asked something similar a while ago here. But that was just about if it was possible to return one. So I guess this question is a response to the one answer I got there =)

推荐答案

我有一个示例实现 你可以看看.它无论如何都不是为了高效而设计的,但它应该可以帮助您入门.

I have a sample implementation you could look at. It's not designed to be efficient by any means, but it should get you started.

基本上一个 IOrderedEnumerable 只需要知道它当前的排序,这样它就可以创建一个新的排序.假设您已经有一个 IComparer,您可以通过以下方式构建一个新的:

Basically an IOrderedEnumerable<T> just needs to have an idea of its current ordering, so it can create a new one. Assuming you already have an IComparer<T> you build a new one by saying something like:

int Compare(T first, T second)
{
    if (baseComparer != null)
    {
        int baseResult = baseComparer.Compare(first, second);
        if (baseResult != 0)
        {
            return baseResult;
        }
    }
    TKey firstKey = keySelector(first);
    TKey secondKey = keySelector(second);

    return comparer.Compare(firstKey, secondKey);        
}

所以基本上你创建了一个从最不重要"到最重要"的比较器链.您还需要将降序"位放在那里,但这很简单:)

So basically you create a chain of comparers going from the "least significant" up to the "most significant". You also need to put the "descending" bit in there, but that's easy :)

在上面链接的示例中,三个不同的方面表示在 MiscUtil 中已经存在的三个不同的类中:

In the sample linked above, the three different aspects are represented in three different classes already present in MiscUtil:

  • ReverseComparer:反转现有IComparer的结果
  • LinkedComparer:从两个创建一个比较器,一主一从
  • ProjectionComparer:基于从原始项目到键的投影创建一个比较器,委托给另一个比较器来比较这些键.
  • ReverseComparer: reverses an existing IComparer<T>'s results
  • LinkedComparer: creates one comparer from two, with one master and one slave
  • ProjectionComparer: creates a comparer based on a projection from the original items to keys, delegating to another comparer to compare those keys.

比较器非常适合像这样链接在一起.

Comparers are great for chaining together like this.

这篇关于C#:如何实现 IOrderedEnumerable<T>的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆