以下均是个人拙见,如果有错误的地方,请大家及时指出,还有代码是在记事本里面敲得,编译可能不会通过,请见谅

对于C#入门者来说,接触的最多的恐怕就是事件了,但现在我们不讲事件,我们就看看委托给我们带来的好处
假设有一个类


class Student

 //这里为了简便就不用属性了
 public int id;
  public string name;
 public int age;
  public int classId;//假设有一个班级编号
 
 public Student(int id,string name,int age,int classId)
 {
  //...
 }
}

class program
{
 static void main(String[] args)
 {
  //声明一个Student的数组,这里大家不要钻牛角尖,
  //为什么不用List或者List<T>呢,因为二者都是微软封装好的数据结构,实现了排序,没必要我画蛇添足
  Student[] s={
    new Student(1004,"成成",19,4),
    new Student(1002,"张才",22,1),
    new Student(1003,"李大为",20,4),
    new Student(1005,"冰冰",23,5)
    new Student(1001,"李晓红",21,3),
    }
                                    //排序
                                   Sort(s);//完成排序

  
    
  
 }
 
 //实现冒泡排序法
 private void  Sort(student[] s)
 {
   for (int i = 0; i < s.Length -1; i++)//控制轮数
                  {
                       for (int j = 0; j < s.Length - 1 - i; j++)//控制交换次数
                       {
                           if s[j].id > s[j + 1].id)
                           {
                              Student temp = S[j];
                                       s[j] = s[j + 1];
                                       s[j + 1] = temp;
                              }
                      }
                  }

 }
}


上面我们通过一个简单的方法实现了根据学号进行排序,该方法无返回值,接收一个Student型的数组,现在满足了命题,没有丝毫的问题。

可新问题来了,我们希望不仅可以通过学生的编号(id)也可以通过学生的年龄(age)进行排序,最容易想到的办法就是用Switch..Case
private void  Sort(student[] s,sting sortfield)
{

 Switch(sortfield)
  case "id":  

   for (int i = 0; i < s.Length -1; i++)//控制轮数
                  {
                       for (int j = 0; j < s.Length - 1 - i; j++)//控制交换次数
                       {
                           if s[j].id > s[j + 1].id)//***********************************
                           {
                              Student temp = S[j];
                                       s[j] = s[j + 1];
                                       s[j + 1] = temp;
                              }
                      }
                  }
  break;

  case "age":
   for (int i = 0; i < s.Length -1; i++)//控制轮数
                   {
                       for (int j = 0; j < s.Length - 1 - i; j++)//控制交换次数
                       {
                           if (s[j].age> s[j + 1].age)//******************************
                           {
                              Student temp = S[j];
                                       s[j] = s[j + 1];
                                       s[j + 1] = temp;
                              }
                      }
                  }
  break;

}

现在调用的时候就变成
 Sort(s,"id")或者Sort(s,"age")
大家注意我打星号的地方,我们是不是可以写出一个方法
 
 //通过Student对象的id进行排序
 private bool CompareById(Student s1,Student s2)
 {
  return s1.id>s2.id;
 }
 
 private bool CompareByAge(Student s1,Student s2)
 {
  return s1.Age>s2.Age;
 }

于是Sort方法变成
private void  Sort(student[] s,sting sortfield)
{

 Switch(sortfield)
  case "id":  

   for (int i = 0; i < s.Length -1; i++)//控制轮数
                  {
                       for (int j = 0; j < s.Length - 1 - i; j++)//控制交换次数
                       {
                           if (CompareById(s[j],s[j+1]))//***********************************
                           {
                              Student temp = S[j];
                                       s[j] = s[j + 1];
                                       s[j + 1] = temp;
                              }
                      }
                  }
  break;

  case "age":
   for (int i = 0; i < s.Length -1; i++)//控制轮数
                   {
                       for (int j = 0; j < s.Length - 1 - i; j++)//控制交换次数
                       {
                           if (CompareByAge(s[j],s[j+1]))//******************************
                           {
                              Student temp = S[j];
                                       s[j] = s[j + 1];
                                       s[j + 1] = temp;
                              }
                      }
                  }
  break;


新的问题又来了,我现在想通过班级号进行排序(当然比喻不一定恰当),最容易想到的办法就是借着加一个case,如果还有其他更多的要求,你将添加更多的case
这当然不利于程序的扩展,粘贴复制是不能适应不断变化的需求的,我们希望我们的方法变成
//实现冒泡排序法
 private void  Sort(student[] s)
 {
   for (int i = 0; i < s.Length -1; i++)//控制轮数
                  {
                       for (int j = 0; j < s.Length - 1 - i; j++)//控制交换次数
                       {
                           if (s[j].id > s[j + 1].id)//**************************CompareById(s[j],s[j+1]或者CompareByAge(s[j],s[j+1])
                           {
                              Student temp = S[j];
                                       s[j] = s[j + 1];
                                       s[j + 1] = temp;
                              }
                      }
                  }

 }
大家注意我打星号的地方,我们现在在这里是不是可以任意传递比较的方法来实现排序,而无须无聊的复制,增加更多的case!
大家知道具有相同特征的东西都可以抽象出一个类,那方法可不可以抽象呢?如果方法可以抽象,我们只需要在打星号的地方写一个形参就可以了
CompareById和CompareByAge有什么相同的特征了,是的,除了方法名字不同,他们具有相同的返回值bool,也具有相同的输入参数,

在这个时候,委托因运而生,委托是什么呢?委托就是方法的一种抽象,就比如你我可以抽象成Person类,
CompareById和CompareByAge抽象后变成
public delegate bool CompareDelegate(Student s1,Student s2);

所以我们的Sort方法 变成
private void  Sort(Student[] s,CompareDelegate method)
 {
   for (int i = 0; i < s.Length -1; i++)//控制轮数
                  {
                       for (int j = 0; j < s.Length - 1 - i; j++)//控制交换次数
                       {
                           if (method(s[j],s[j+1]))//调用
                           {
                              Student temp = S[j];
                                       s[j] = s[j + 1];
                                       s[j + 1] = temp;
                              }
                      }
                  }

 }

所以现在的调用变成了
Sort(s,CompareById)或者Sort(s,CompareByAge);

如果你现在想根据班级排序,简单,写一个方法
private bool CompareByClassid(Student s1,Student s2)
{
 return s1.classid>s2.classid;
}

然后调用变成Sort(s,CompareByClassid),可扩展性你也看到了

最后总结一下,委托是对方法的一种抽象

 

谢谢各位光顾我的博客,如果能留下你的脚印,我将不甚荣幸

posted on 2010-10-26 16:07  一本好正经  阅读(993)  评论(7编辑  收藏  举报