C# 委托的使用及概念

 基础概述
(1)委托是用来封装方法的类型,遵循观察者设计模式,类似于C和C++的函数指针。委托是面向对象的、且类型安全可靠。
(2)委托类型派生自.NET Framework中的System.Delegate类,委托类型是封装的,所以不能被派生。
(3)对委托实例化后,委托会对其进行的方法调用与参数传递到该方法,并且委托会将方法的的返回值返回到调用方,这被称为调用委托。
(4)委托的定义:委托是一种数据类型,和类是同级的,委托和类都  是方法的载体。
(5)委托是方法的抽象,它存储的就是一系列具有相同签名和返回回类型的方法的地址。
(6)调用委托时,委托的所有方法都将被执行。
(7)委托是C#中的特色,通常将委托分为命名方法委托、多播委托、匿名委托。
 
语法使用
(1)委托的声明:delegate  返回类型  委托名 (参数);
(2)委托的实例化:委托名  实例化名 = new 委托名 (函数名);
(3)匿名方法实例化:委托类型  实例化名 = delegate ( 函数参数 ) { 函数体 };
(4)调用委托:委托名(参数 );
//声明委托
public delegate int MyDelegate(int num);

public static void Method1(int num)
{
    Console.WriteLine("Method1被调用了,传入的参数是:" + num);
}

static void Main(string[] args)
{
   //1、实例化委托,使用new关键字
    MyDelegate del01=new MyDelegate(Method1);

  //2、使用匿名方法
  MyDelegate del02=delegate(int x, int y)
  {
     return x + y;
  }

  //3、使用lambda表达式
  MyDelegate del03=(int x, int y) => { return x + y };

  //4、调用
  del01(25);
}

 

委托的多播(Multicasting of a Delegate)
(1)多个相同类型的委托对象可以使用“+”进行合并,或使用“-”移除合并的委托
(2)委托可以注册多个函数,这样的委托称之为“多播”或“组播”“委托链”,执行委托时根据注册顺序依次执行注册的函数
class Program
{
    //声明委托
    public delegate void OrderDelegate();
    static void Main(string[] args)
    {
        //实例化两个委托
        OrderDelegate orderDelegate = new OrderDelegate(Order.BuyFood);
        OrderDelegate ccDel= new OrderDelegate(Order.BuyFlower);
        //向委托中注册方法
        orderDelegate += Order.BuyCake;
        //合并其它同类型委托
        orderDelegate += ccDel;
        //调用委托
        orderDelegate();
    }
}
class Order
{
    public static void BuyFood()
    {
        Console.WriteLine("购买快餐!");
    }
    public static void BuyCake()
    {
        Console.WriteLine("购买蛋糕!");
    }
    public static void BuyFlower()
    {
        Console.WriteLine("购买鲜花!");
    }
}
//最后输出:购买快餐!购买蛋糕!购买鲜花!

 

事件(EVENT)
(1)事件就是一个狭义的委托,委托是具有相同签名的函数的载体,事件是委托的应用方式之一。
(2)事件是引用类型,事件封装了委托链,所以事件必须配合委托使用
 
事件和委托的区别
  1. 通俗来讲,委托可以在客户代码中直接调用从而激发委托指向的函数,而事件的触发只能由服务代码自己触发。
  2. 也就是说委托你不仅可以安排谁是它的调用函数,还可以直接调用它,而事件不能直接调用,只能通过某些操作触发。
//创建一个委托
public delegate void WaterHeaterDelegate(int Temperature);

class WaterHeater{
        //创建一个烧水事件
    public event WaterHeaterDelegate WaterDele;

    public void Shaoshui() //烧水函数
    {
        for (int i = 0; i <= 100; i++)
        {
            if (i > 95)
            {
                WaterDele.Invoke(i); //当水温达到95度以上,调用事件
            }
        }
    }
    public void WaterHot(int temperature) //水温提示函数
    {
        Console.WriteLine("水已经有{0}C了", temperature);
    }

    public void WaterBoiling(int temperature) //水烧开函数
    {
        Console.WriteLine("水已经烧开了"+ temperature);
    }
}

class Program
{
    static void Main(string[] args)
    {
        //方法一:绑定外部类中的方法
        WaterHeater water = new WaterHeater();  //热水器实例化对象
        water.WaterDele += new WaterHeaterDelegate(water.WaterHot); //绑定事件
        water.WaterDele += new WaterHeaterDelegate(water.WaterBoiling); //绑定事件
        //water.WaterDele += (new WaterHeater()).WaterHot; //绑定事件的 另一种形式
        water.Shaoshui();

        //方法二:绑定内部类中的方法
        //water.WaterDele += Water_WaterDele;
        //water.WaterDele += Water_WaterDele1;
        //water.Shaoshui();
    }

    private static void Water_WaterDele1(int Temperature)
    {
        Console.WriteLine("水已经烧开了" + Temperature);
    }

    private static void Water_WaterDele(int Temperature)
    {
        if (Temperature == 100)
        {
            Console.WriteLine("水已经有{0}C了", Temperature);
        }
    }
}
 
Action与Func内置委托
(1)除了自定义命名方法委托之外,系统还提供了内置委托类型→Action和Func。
(2)Action可以定义返回值为void的委托,同时可在泛型列表中定义0到16个函数参数。
(3)Func可以定义具有返回值的委托,同时可在泛型列表中定义0到16个函数参数。
(4)Func的泛型列表中最右一位用来定义返回值类型,若泛型列表只有一个类型,则表示无参带返回值委托。
 
Action和Func的区别
  1. Action用于没有返回值的方法(参数根据自己的需求进行传递)
  2. Func相反,它用于有返回值的方法(同样根据自己的需求而定)
  3. 记住无返回值用action,有返回值用Func
class Program
{
   public static void Main()
   {
      //实例化Action委托
      Action<int, int, int> testAction = new Action<int, int, int>(AddNumMethod);
           testAction(1, 2, 3);

      //实例化一个Func委托(无参返回值为string)
      Func<string> testFunc1=new Func<string>(testFuncMethod1);
      testFunc2();

      //实例化一个Func委托(带参返回值为string)
      Func<int, int, string> testFunc2=new Func<int, int, string>(testFuncMethod2);
      testFunc2(1, 2);

   }
   //Action测试方法
   private static void AddNumMethod(int num1, int num2, int num3)
   {
      Console.WriteLine(num1 + num2 + num3);      
   }
   //Func测试方法一
   private static string testFuncMethod1()
   {
      Console.WriteLine("Func委托测试成功!");      
   }
   //Func测试方法二
   private static string testFuncMethod2(int num1, int num2)
   {
      Console.WriteLine("数值的和是:" + (num1 + num2));      
   }
}

 

 
 
 
 
 
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值