Jie

心若无尘,一花一世界,一鸟一天堂;心若静,已如涅磐,风声物语,皆可成言.
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

IComparable and IComparer

Posted on 2008-02-16 22:08  JieNet  阅读(506)  评论(0)    收藏  举报
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;


namespace Sample_IComparable_and_IComparer
{
    
/// <summary>
    
/// Course Enum 课程枚举
    
/// </summary>
    public enum CourseEnum
    {
        Chinese 
=0,
        Math,
        English,
        Total
    }

    
/// <summary>
    
/// Scores class 分数类,用于记录学生的分数
    
/// </summary>
    public class Scores
    {
        
int[] score = new int[4];

        
public int this[CourseEnum course]
        {
            
get { return score[(int)course]; }
            
set
            {
                score[(
int)course] = value;
            }
        }

        
public override string ToString()
        {
            StringBuilder sbScore 
= new StringBuilder();
            sbScore.Append(
"Chinese:");
            sbScore.Append(score[
0]);
            sbScore.Append(
"   ");

            sbScore.Append(
"Math:");
            sbScore.Append(score[
1]);
            sbScore.Append(
"   ");

            sbScore.Append(
"English:");
            sbScore.Append(score[
2]);
            sbScore.Append(
"   ");

            sbScore.Append(
"Total:");
            sbScore.Append(score[
3]);

            
return sbScore.ToString();
        }
    }


    
/// <summary>
    
/// Student Class 继承 IComparable。IComparable接口定义了类型的自然排序方式。
    
/// </summary>
    public class StudentComparable : IComparable
    {
        
string name;
        Scores score 
= new Scores();

        
public StudentComparable(string name, int chinese, int math, int english)
        {
            
this.name = name;
            
this.score[CourseEnum.Chinese] = chinese;
            
this.score[CourseEnum.Math] = math;
            
this.score[CourseEnum.English] = english;
            
this.score[CourseEnum.Total] = chinese + math + english;
        }

        
public string Name
        {
            
get { return this.name; }
            
set { this.name = value; }
        }

        
public Scores Score
        {
            
get { return this.score; }
            
set { this.score = value; }
        }


        
//显示实现接口,该方法在类型上不够安全。必须检查参数的运行时类型
        
//此方法要执行装箱和拆箱来进行实际的比较
        
//用此方法。如果Student[] student = new Student[99999];或者更大的时候,就知道“爽”就一个字了。
        int IComparable.CompareTo(object obj)
        {
            
if (obj is StudentComparable)
            {
                StudentComparable s 
= obj as StudentComparable;
                
return this.CompareTo(s);//升序。
                
//return this.CompareTo(s) * -1;//降序。
            }

            
throw new ArgumentException("obj is not a StudentComparable");
        }

        
//为接口中的方法提供一个公有的强类型重载版本
        
//优点:强类型,方便(至少能少打几个字母-_-#)
        public int CompareTo(StudentComparable stu)
        {
            
//执行 String.CompareTo 方法 (String)
            
//此方法性能优于CompareTo(object obj)方法
            
//很明显String.CompareTo 方法 (String) 没有拆箱
            return this.name.CompareTo(stu.name);
        }
        

        
public override string ToString()
        {
            
return this.name + " : " + this.score.ToString();
        }
    }


    
/// <summary>
    
/// StudentComparer Class。继承 IComparer。IComparer则为类型提供了另外的排序方式。
    
/// </summary>
    public class StudentComparer : IComparer
    {
        StudentComparable[] sc;
        CourseEnum course;

        
int IComparer.Compare(object x, object y)
        {
            
if(!(x is StudentComparable))
                
throw new ArgumentException("obj is not a StudentComparable");
            
if(!(y is StudentComparable))
                
throw new ArgumentException("obj is not a CourseEnum");

            StudentComparable left 
= x as StudentComparable;
            StudentComparable right 
= x as StudentComparable;

            
return Compare(left, right);
            
        }

        
public int Compare(StudentComparable left, StudentComparable right)
        {
            
return left.Score[course].CompareTo(right.Score[course]);     //升序
            
//return left.Score[course].CompareTo(right.Score[course]) * -1;  //降序
        }

        
public StudentComparable[] Sc
        {
            
get { return sc; }
            
set { sc = value; }
        }

        
public StudentComparer(StudentComparable[] sc, CourseEnum course)
        {
            
this.sc = sc;
            
this.course = course;
        }

        
public override string ToString()
        {
            
return sc.ToString();
        }

    }


    
/// <summary>
    
/// Test Class
    
/// </summary>
    public class TestClass
    {

        
public static void Main()
        {

            Console.WriteLine(
"***** IComparable 根据姓名排序*****\n");

            StudentComparable[] student 
= new StudentComparable[4];
            student[
0= new StudentComparable("C"608080);
            student[
1= new StudentComparable("A"707070);
            student[
2= new StudentComparable("D"909090);
            student[
3= new StudentComparable("B"80100100);

            Array.Sort(student);
//调用 int IComparable.CompareTo(object obj)

            
foreach (StudentComparable stu in student)
            {
                Console.WriteLine(stu);
            }

            StudentComparable[] student2 
= new StudentComparable[2];
            student2[
0= new StudentComparable("A"808080);
            student2[
1= new StudentComparable("B"707070);
            
//调用 public int CompareTo(Student stu)
            Console.WriteLine("\n\"{0}\".CompareTo(\"{1}\") : {2}", student2[0].Name, student2[1].Name, student2[0].CompareTo(student2[1]));



            Console.WriteLine(
"\n\n***** IComparer 根据总成绩排序 *****\n");

            StudentComparer sc 
= new StudentComparer(student, CourseEnum.Total);
            Array.Sort(sc.Sc, sc.Compare);
//调用 public int Compare(StudentComparable left, StudentComparable right)
            foreach (StudentComparable s in sc.Sc)
            {
                Console.WriteLine(s.ToString());
            }

            Console.WriteLine(
"\n\n***** IComparer 根据语文成绩排序 *****\n");

            StudentComparer sc2 
= new StudentComparer(student, CourseEnum.Chinese);
            Array.Sort(sc2.Sc, sc2.Compare);
            
foreach (StudentComparable s in sc2.Sc)
            {
                Console.WriteLine(s.ToString());
            }

            Console.Read();

        }
    }

}
//namespace

结果如下:

***** IComparable 根据姓名排序*****

A : Chinese:70   Math:70   English:70   Total:210
B : Chinese:80   Math:100   English:100   Total:280
C : Chinese:60   Math:80   English:80   Total:220
D : Chinese:90   Math:90   English:90   Total:270

"A".CompareTo("B") : -1


***** IComparer 根据总成绩排序 *****

A : Chinese:70   Math:70   English:70   Total:210
C : Chinese:60   Math:80   English:80   Total:220
D : Chinese:90   Math:90   English:90   Total:270
B : Chinese:80   Math:100   English:100   Total:280


***** IComparer 根据语文成绩排序 *****

C : Chinese:60   Math:80   English:80   Total:220
A : Chinese:70   Math:70   English:70   Total:210
B : Chinese:80   Math:100   English:100   Total:280
D : Chinese:90   Math:90   English:90   Total:270