当前位置:编程学习 > asp >>

.NET Framework 中的设计模式——应用策略模式为List排序

 编程时遇到排序在平常不过,使用.Net最常见的就是对泛型List<T>进行排序,如果T是简单数据类型排序那么很简单,直接调用List的Sort()方法就可以了,但是如果我们要排的对象复杂了怎么办,我们知道List<T> sort()最后是用快速排序实现,快速排序也好,什么排序都需要知道list中item之间的比较结果,如果是简单的int类型,直接判断即可,对实现了IComparable接口的对象,可以调用其CompareTo()实现item比较大小,下面是一个快速排序的写法


void Sort<T>(T[] array, int left, int right, IComparer_sly<T> comparer) where T : IComparable
        {
            if (left < right)
            {
                T middle = array[(left + right) / 2];
                int i = left - 1;
                int j = right + 1;
                while (true)
                {
                    while (array[++i].CompareTo(middle) < 0) ;

                    while (array[--j].CompareTo(middle) > 0) ;

                    if (i >= j)
                        break;

                    T temp = array[i];
                    array[i] = array[j];
                    array[j] = temp;
                }

                Sort(array, left, i - 1, comparer);
                Sort(array, j + 1, right, comparer);
            }
        }

 

 

问题

对于前两种情况固然可以实现排序,但是我们不可能要求所有待排序的对象都实现IComparable接口,就算能够保证每个对象都实现IComparable接口,如果想实现对象内多个字段排序,比如Student对象,有时候想按照姓名排序,有时候是成绩,有时候是年龄,这怎么破

按照面向对象的思想,要把变化独立出来,封装变化,对于我们排序List<T>时变化的其实就是怎么比较两个对象的大小的算法,如果我们可以把这个算法拿出来,排序就简单了很多,无论什么排序,算法都是由的,我们要封装的部分是怎样比较两个item的大小的算法,为了实现拓展性我们要遵循面向对象设计的另外一个重要原则,针对接口编程,而不是针对实现编程。

编写通用的List<T>排序方法首先定义一个接口,里面有一个比较item大小的方法,在排序的时候作为参数传入,当然是传入它的实现类,有了这个想法,我们可以自己写个List<T>的排序方法

public interface IComparer_sly<T>{
        int Compare(T x, T y);
}

 

然后为了测试,我们为List<T>加一个包装,写一个自己的Sort方法,内部也用快速排序实现。一直困惑我们的变化部分——比较大小算法,我们把它封转起来,作为参数传入


using System;
using System.Collections.Generic;

namespace Test.Stategy
{public class ListTest<T>
    {
        public List<T> list = new List<T>();
        public void Sort(IComparer_sly<T> comparer)
        {
            T[] array = list.ToArray();
            int left = 0;
            int right = array.Length - 1;
            QuickSort(array, left, right, comparer);
            list = new List<T>(array);
        }

        private void QuickSort<S>(S[] array, int left, int right, IComparer_sly<S> comparer)
        {
            if (left < right)
            {
                S middle = array[(left + right) / 2];
                int i = left - 1;
                int j = right + 1;
                while (true)
                {
                    while (comparer.Compare(array[++i], middle) < 0) ;

                    while (comparer.Compare(array[--j], middle) > 0) ;

                    if (i >= j)
                        break;

                    S temp = array[i];
                    array[i] = array[j];
                    array[j] = temp;
                }

                QuickSort(array, left, i - 1, comparer);
                QuickSort(array, j + 1, right, comparer);
            }
        }
    }
}比如现在我们有个Student 的实体


public class Student
    {
        public Student(int id, string name)
        {
            this.ID = id;
            this.Name = name;
        }
 &n

补充:Web开发 , ASP.Net ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,