使用過如泛型 List 的人都知道, 當我有數值要排序的時候很簡單, 因為這是泛型具備的功能.  可是當自訂的 Class 要怎樣做呢?
其實很簡單, 只要繼承自 IComparable, 外加實做 CompareTo Method 就可以了. 看看 List.Sort 的說明及其多型就知道了.

這個方法會使用型別 T 的預設比較子 Comparer<T>.Default,以判斷清單項目的順序。 Comparer<T>.Default 屬性會檢查型別 T 是否實作 IComparable<T> 泛型介面,並使用該實作 (如果可用的話)。 如果不是,則 Comparer<T>.Default 會檢查型別 T 是否實作 IComparable 介面。 如果型別 T 不實作這兩種介面,則 Comparer<T>.Default 會擲回 InvalidOperationException。

List.Sort ()   使用預設比較子來排序在整個 List 中的項目。
List.Sort (泛型 Comparison)   使用指定的 System.Comparison 來排序在整個 List 中的項目。
List.Sort (泛型 IComparer)   使用指定的比較子來排序在整個 List 中的元素。

如下範例, 我們有一個 Student Class, 我想要依據學號(ID)排序, 就只要這樣做就可以.

using System;
using System.Collections.Generic;
using System.Text;

namespace IComparable
{
    class Student : IComparable<Student>
    {
        public string Name;
        public string ID;
        public double Score;
        public Student(string Name, string ID, double Score)
        {
            this.Name = Name;
            this.ID = ID;
            this.Score = Score;
        }

        /// <summary>
        /// 時做依據 ID 比較
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public int CompareTo(Student value)
        {
            return this.ID.CompareTo(value.ID);
        }
        
        
    }
    class Program
    {
        static void Main(string[] args)
        {
            List<Student> Students = GetStudents();
            Students.Sort();
            ShowStudent(Students);
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }

        static List<Student> GetStudents()
        {
            List<Student> Students = new List<Student>();
            Student Jack = new Student("Jack","005", 90);
            Student Mary = new Student("Mary", "001", 95.5);
            Student Jessica = new Student("Jessica", "002", 85);
            Students.Add(Jack);
            Students.Add(Mary);
            Students.Add(Jessica);
            return Students;
        }

        static void ShowStudent(List<Student> Students)
        {
            foreach (Student value in Students)
            {
                Console.WriteLine(value.Name.PadRight(10) + value.ID.PadRight(10) + value.Score.ToString());
            }
        }

    }
}

 
如果想要依據成績(Score)排序呢?
1. 你可以哪上面的 CompareTo Method 改掉就可以.
2. 但這樣遜了一點, 不能提供可以依據 學號(ID), 成績(Score) 排序的功能, 讓我依需求再決定要怎樣排.
3. 另一種是使用委派().
 
現在我們先來看看, 如果要增加另一欄位的排序, 要怎樣做? 以下實做一個依據成績(Score)的 Comparer.
    class CompareByScore : IComparer<Student>
    {
        public int Compare(Student a, Student b)
        {
            return a.Score.CompareTo(b.Score);
        }
    }
未來在執行排序時指定 Comparer 就行了, 如下.
Students.Sort(new CompareByScore());

using System;
using System.Collections.Generic;
using System.Text;

namespace IComparable
{
    class CompareByScore : IComparer<Student>
    {
        public int Compare(Student a, Student b)
        {
            return a.Score.CompareTo(b.Score);
        }
    }

    class Student : IComparable<Student>
    {
        public string Name;
        public string ID;
        public double Score;
        public Student(string Name, string ID, double Score)
        {
            this.Name = Name;
            this.ID = ID;
            this.Score = Score;
        }

        /// <summary>
        /// 時做依據 ID 比較
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public int CompareTo(Student value)
        {
            return this.ID.CompareTo(value.ID);
        }
        
        
    }
    class Program
    {
        static void Main(string[] args)
        {
            List<Student> Students = GetStudents();
            Console.WriteLine("Sort by ID");
            Students.Sort();
            ShowStudent(Students);
            Console.WriteLine("Sort by Score");
            Students.Sort(new CompareByScore());
            ShowStudent(Students);
            Console.WriteLine("Sort by Name(method)");
            Students.Sort(CompareByName);
            ShowStudent(Students);
            Console.WriteLine("Sort by ID(delegate)");
            Students.Sort(delegate(Student a, Student b) { return Comparer<string>.Default.Compare(a.ID, b.ID); });
            ShowStudent(Students);
            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }

        private static int CompareByName(Student a, Student b)
        {
            return a.Name.CompareTo(b.Name);
        }

        static List<Student> GetStudents()
        {
            List<Student> Students = new List<Student>();
            Student Jack = new Student("Jack","005", 90);
            Student Mary = new Student("Mary", "001", 95.5);
            Student Jessica = new Student("Jessica", "002", 85);
            Students.Add(Jack);
            Students.Add(Mary);
            Students.Add(Jessica);
            return Students;
        }

        static void ShowStudent(List<Student> Students)
        {
            foreach (Student value in Students)
            {
                Console.WriteLine(value.Name.PadRight(10) + value.ID.PadRight(10) + value.Score.ToString());
            }
        }

    }
}
 
Sort by ID
Mary      001       95.5
Jessica   002       85
Jack      005       90
Sort by Score
Jessica   002       85
Jack      005       90
Mary      001       95.5
Sort by Name(method)
Jack      005       90
Jessica   002       85
Mary      001       95.5
Sort by ID(delegate)
Mary      001       95.5
Jessica   002       85
Jack      005       90
Press any key to exit

arrow
arrow
    全站熱搜

    py3939 發表在 痞客邦 留言(0) 人氣()