• 为什么要使用委托?


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

    对于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),可扩展性你也看到了

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

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

  • 相关阅读:
    [WinJS] Promise 用法
    Python 统计代码行
    mac下Apache + MySql + PHP网站开发
    android中,获取网速的方法实现
    如何屏蔽掉两个activity切换时的动画效果
    dp与px的相互转化
    毫秒的格式化
    关于android中事件传递和分发的一些小理解
    汉字转拼音
    关于实现无限循环的做法
  • 原文地址:https://www.cnblogs.com/hcfight/p/weituo.html
Copyright © 2020-2023  润新知