zoukankan      html  css  js  c++  java
  • 委托的基本知识

    委托是一种数据结构,它引用静态方法或者引用类实例及该类的实例方法(MSDN);

    委托类型的声明,建立了一个协定,该协定指向一个或者多个方法的签名;

    委托是面向对象并且是类型安全的。

    一、Delegate的简单例子:

    委托的声明需要使用关键字:delegate;

    委托的命名是任意的,但是委托必须与它指向的方法签名相匹配:返回类型、参数个数与类型。

    namespace ConsoleApplication1

    {
          //定义委托,可以指向任何这样的方法:返回值 为 Int型,并且有两个Int参数    

       public delegate int MathDelegate(int x,int y);    

       public class DelegateDemo   
       {        

          public static int Add(int x, int y){returnx + y;}        

          public static int Multiply(int x, int y){returnx * y;}        

          public static int Subtract(int x, int y){returnx - y;}    

       }    

       public classProgram   

       {
              static voidMain(string[] args)        

         {            

          //创建一个委托实例,指向DelegateDemo.Add()方法             

          MathDelegate math1 = newMathDelegate(DelegateDemo.Add);             //调用Add()使用委托            

          Console.WriteLine("100 + 20 = {0}", math1(100, 20));            

          //创建一个委托实例,指向DelegateDemo.Multiply()方法            

          MathDelegate math2 = newMathDelegate(DelegateDemo.Multiply);            

          Console.WriteLine("100 * 20 = {0}", math2(100, 20));
                   Console.ReadLine();        

         }
           }

    }

    二、委托的多播(Multicast)

    多播是指一个委托对象可以指向多个方法,而不是仅仅是指向一个方法;

    采用 += 添加方法,-= 移走方法

    多播委托指向的方法的 返回值 一般是void,当然如果有返回值的话,那么仅能得到最后一个方法的返回值

    namespace ConsoleApplication1 {
    //定义委托,可以指向任何这样的方法:返回值 为 Int型,并且有两个Int参数
      public delegate int MathDelegate(int x,int y);
      public class DelegateDemo
      {
        public static int Add(int x, int y)
        {
          Console.WriteLine("加法的结果:");
          Console.WriteLine("{0} + {1} = {2} ", x, y, x + y);
    return x + y;
        }
        public static int Multiply(int x, int y)
        {
          Console.WriteLine("乘法的结果:");
    Console.WriteLine("{0} * {1} = {2} ", x, y, x * y);
    return x * y;
        }
        public static int Subtract(int x, int y)
        {
          Console.WriteLine("减法的结果:");
    Console.WriteLine("{0} - {1} = {2} ", x, y, x - y);
    return x - y;
        }
      }
      public class Program
      {
    static void Main(string[] args)
         {
          //创建一个委托实例,指向DelegateDemo.Add()方法
          MathDelegate math = new MathDelegate(DelegateDemo.Add);
          //使用上述创建的相同的实例,调用DelegateDemo.Multiply()方法 和 DelegateDemo.Subtract()方法
          math += new MathDelegate(DelegateDemo.Multiply);
          math += new MathDelegate(DelegateDemo.Subtract);
    int result = math(100, 20);
          Console.WriteLine("委托调用结果:{0}",result);
    Console.ReadLine();
        }
    }
    }

    三、委托协变和逆变

    将方法签名与委托类型匹配时,协变和逆变可以提供一定程度的灵活性;

    协变允许方法具有的派生返回类型比委托中定义的更多;

    逆变允许方法具有的派生参数类型比委托类型中的更少;(MSDN)

    namespace ConsoleApplication1 
    {
      public delegate Person PersonDelegate();
      public class DelegateCovariance
      {
        public static Person GetPerson() { return new Person(); }
    public static Student GetStudent() { return new Student(); }
        static void Main(string[] args)
        {
          PersonDelegate personDelegate = new PersonDelegate(GetPerson);
          Person person = personDelegate();
          Console.WriteLine("Person:{0}", person.ToString());
    PersonDelegate studentDelegate = new PersonDelegate(GetStudent);
    Student student = (Student)studentDelegate();//如果没有强类型转换,则不能通过编译 Console.WriteLine("Student:{0}", student.ToString());
    Console.ReadLine();
        }
      }
    public class Person
      {
    protected string _firstName;
         protected string _lastName;
         protected int _age;
    public Person()
         {
          this._firstName = "Smith";
          this._lastName = "Jack";
          this._age = 20;
         }
        public override string ToString()
        {
          return string.Format("FirstName:{0} LastName:{1} Age:{2}", _firstName, _lastName, _age);
        }
      }
      public class Student : Person
      {
        protected string _height;
        public Student() : base() { _height = "175cm"; }
        public override string ToString()
        {
          return string.Format("FirstName:{0} LastName:{1} Age:{2} Height:{3}", _firstName, _lastName, _age, _height);
        }
      }
    }
  • 相关阅读:
    Dubbo框架——整体架构
    ie8不支持的数组方法
    前端面试问题
    Cookie和WebStorage的区别
    flex部局 API
    组合继承介绍
    克隆节点
    键盘事件
    js动态创建元素和删除
    js中的节点属性 和上下级访问关系
  • 原文地址:https://www.cnblogs.com/yaosuc/p/4736455.html
Copyright © 2011-2022 走看看