委托的基本知识

委托是一种数据结构,它引用静态方法或者引用类实例及该类的实例方法(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);
    }
  }
}
原文地址:https://www.cnblogs.com/yaosuc/p/4736455.html