独上高楼网站
  •    你所在位置:首页 VS.netC#C#高级编程(4版)〉反转Sorted List里的内容
  • 反转Sorted List里的内容
  • 作者:abatei  文章来源:博客园  发布日期:2008-02-21  浏览次数:209
  • 打印这篇文章
  • 问题

    您希望在数组和列表类型中可以反转sorted list里的内容同时又维持SortedListSortedList< T>类原来的功能。无论是SortedList还是泛型SortedList< T>类都直接提供了完成这个功能的方法而又不需要重填列表。

    解决方案

    ReversibleSortedList< TKey, TValue>类提供了这些功能,它基于SortedList< TKey, TValue>类,所以拥有相同的功能,它提供了额外的功能是很容易反转已排序的列表。

    在实例化ReversibleSortedList< TKey, TValue>之后,键是整数类型,值是字符串类型,一连串无序的数字和它们的文本表达被插入到列表中。这些项目是这样显示的:

    ReversibleSortedList< intstring> rsl = new ReversibleSortedList< intstring>();
    rsl.Add(
    2"2");
    rsl.Add(
    5"5");
    rsl.Add(
    3"3");
    rsl.Add(
    1"1");
    foreach (KeyValuePair< intstring> kvp in rsl)
    {
        Debug.WriteLine(
    "\t" + kvp.Key + "\t" + kvp.Value);
    }

     

    列表输出显示为按升序排序(默认):

        1   1
        2   2
        3   3
        5   5

    现在排列顺序通过设置ReversibleSortedList的SortDirection属性被反转为降序。为了重新排序需要调用Sort()方法。结果如下:

    // 转换排序方向.
    rsl.Comparer.SortDirection = ListSortDirection.Descending;
    // 重排列表.
    rsl.Sort();
    foreach (KeyValuePair< intstring> kvp in rsl)
    {
        Debug.WriteLine(
    "\t" + kvp.Key + "\t" + kvp.Value);
    }

     

    这一次,输出为降序:

        5   5
        3   3
        2   2

    1   1

    当把一个新项添加进列表,它将按当前的排列顺序被添加进去,但在添加完所有项后马上进行反转,就可以保持列表中元素的顺序。

    rsl.Add(4"4");
        
    foreach (KeyValuePair< intstring> kvp in rsl)
        
    {
            Debug.WriteLine(
    "\t" + kvp.Key + "\t" + kvp.Value);
        }

        
    // 转换排序方向.
        rsl.Comparer.SortDirection = ListSortDirection.Ascending;
        
    // 重排列表.
        rsl.Sort();
        
    foreach (KeyValuePair< intstring> kvp in rsl)
        
    {
            Debug.WriteLine(
    "\t" + kvp.Key + "\t" + kvp.Value);
    }

     

    可以看到新项即按降序也按升序排列:

        5   5
        4   4
        3   3
        2   2
        1   1
        1   1
        2   2
        3   3
        4   4
        5   5

     

    ReversibleSortedList< TKey, TValue>包含一个实现了IComparer< T>接口的嵌套类SortDirectionComparer< T>。这个类可以在“讨论”这一节中的ReversibleSortedList< TKey, TValue>代码中看到。一个实现了IComparer< T>接口的类可以做为ReversibleSortedList< TKey, TValue>构造方法的参数来改变默认的排序。IComparer< T>接口实现了Compare方法:

    class Program
        
    {
            
    public int Compare(T lhs, T rhs)
            
    {
                
    int compareResult =
                    lhs.ToString().CompareTo(rhs.ToString());
                
    // 如果为降序, 则反转
                if (SortDirection == ListSortDirection.Descending)
                    compareResult 
    *= -1;
                
    return compareResult;
            }

    }

     

    Compare方法使用了SortDirectionComparer< T>类的SortDirection属性来决定项的排序。这个属性在ReversibleSortedList< TKey, TValue>的内部类SortDirectionComparer< T>实例中被设置。SortDirection属性是在构造方法中被设置的,代码如下:

     public ReversibleSortedList()
        
    {
            
    this.keys = ReversibleSortedList< TKey, TValue>.emptyKeys;
            
    this.values = ReversibleSortedList< TKey, TValue>.emptyValues;
            
    this._size = 0;
            
    this._sortDirectionComparer = new SortDirectionComparer< TKey>();
            
    this._currentSortDirection = this._sortDirectionComparer.SortDirection;
    }

     

    这允许它在指定时间内反转排列顺序,但并没有重排列表中已存在的项。为了实现这个功能,需要在Reversible-SortedList< TKey, TValue>类中添加一个新的Sort()方法以重排列表。代码如下:

    public void Sort()
    {
        
    //检查是否跟现有排序方向相同.
        if (this._currentSortDirection != this._sortDirectionComparer.SortDirection)
        
    {
            
    // 如果不同,则进行反转.
            Array.Reverse(this.keys, 0this._size);
            Array.Reverse(
    this.values, 0this._size);
            
    // 设置当前排序.
            this._currentSortDirection = this._sortDirectionComparer.SortDirection;
         }

    }

     

    讨论

    4-3是ReversibleSortedList< TKey, TValue>类的所有代码:

    (译者注:这个类的代码很恐怖,接近1300行,不过代码很规范,感觉应该是商业代码,非常值得借鉴。将来有时间我会专门写文章分析它。请关注:我的博客:http://cgbluesky.blog.163.com/)

    4-3 ReversibleSortedList类

    [Serializable, ComVisible(false), DebuggerDisplay("Count = {Count}")]
    public class ReversibleSortedList< TKey, TValue> :
            IDictionary
    < TKey, TValue>, ICollection< KeyValuePair< TKey, TValue>>,
            IEnumerable
    < KeyValuePair< TKey, TValue>>,
            IDictionary, ICollection, IEnumerable
    {
        
    SortDirectionComparer类定义 // SortDirectionComparer

        
    构造方法