C#基本笔记(3)—— C# 委托

C#委托

1. 委托的定义和使用

  • 委托的作用:如果要把方法作为函数来进行传递的话,就要用到委托。委托是一个类型,这个类型可以赋值一个方法的引用。C#的委托 通过 delegate 关键字来声明。

  • 声明委托的方式:

    // 第一种方式
    delegate void MyDelegate_1(int x);
    // 第二种方式
    delegate void MyDelegate_2<T>(T x);
  • 使用委托的方式:

    // 第一种方式
    MyDelegate_1 mydelegate = new MyDelegate_1( func );
    // 第二种方式
    MyDelegate_1 mydelegate = func;
  • 委托调用方法

    // 例子
    public class Delegate : MonoBehaviour
    {
       public delegate void ShowDelegate();
       public delegate double MultiplyDelegate(double x, double y);
       void Start()
      {
           ShowDelegate show = new ShowDelegate(Show_1);
           MultiplyDelegate mul = Multiply;
           // 直接调用
           show();
           Debug.Log(mul(2f, 3f));
           // 调用invoke方法
           show.Invoke();
           Debug.Log(mul.Invoke(2f, 3f));
      }
       public void Show_1()
      {
           Debug.Log("Show1");
      }
       public double Multiply(double x, double y)
      {
           return x * y;
      }
    }

     

 

2. 系统内置Action委托

Action委托:

  • Action<T>是 .NET Framework 内置的泛型委托,可以使用 Action<T>委托以参数形式传递方法,而不用显式声明自定义的委托。

  • 封装的方法必须与此委托定义的方法签名相对应。即 封装的方法必须具有一个通过值传递给它的参数,并且不能有返回值。 还有一种是非泛型委托 Action

注意:

  • Action委托至少 0 个参数,至多 16 个参数,无返回值;

  • Action表示无参,无返回值的委托;

  • Action<int, string>表示有传入参数intstring无返回值的委托;

  • Action<int, string, bool>表示有传入参数intstringbool无返回值的委托;

  • Action<int, int, int, int>表示有传入4个int型参数,无返回值的委托。

// 案例
// 使用Action、Func等委托时,需要添加 using System;
public class SystemAction : MonoBehaviour
{
   void Start()
  {
       // 无参
       Action action_1 = Show_1;
       action_1();

       // 带参
       Action<int, int> action_2 = Show_2;
       action_2(1, 2);

  }
   void Show_1()
  {
       Debug.Log("Show_1");
  }
   void Show_2(int a, int b)
  {
       Debug.Log("Show_2 " + (a + b));
  }
}

 

3. 系统内置Func委托

Func委托:Func是 .NET Framework 内置的带有返回类型的泛型委托

注意:

  • Func至少 0 个输入参数,至多 16 个输入参数,根据返回值泛型返回。必须有返回值,不可用void

  • Func<int>表示没有输入参数,返回值为int类型的委托;

  • Func<object, string, int>表示传入参数为objectstring,返回值类型为int的委托;

  • Func<T1, T2, T3, int>表示传入参数为T1, T2, T3(泛型),返回值为int类型的委托。

/**
* System.Func 可以不带参数,但是必须带一个返回值
* System.Func 若是调用的多个泛型的委托定义,最后参数的数据类型是函数的返回值类型,需要保持一致;
* 非最后一个泛型的声明,需要与实现函数的参数个数及类型保持一致
*/
public class SystemFunc : MonoBehaviour
{
   void Start()
  {
       // 不带参数,返回值为string类型
       Func<string> func_1 = Show_1;
       string a = func_1();
       Debug.Log(a);
       // 带int类型参数,返回值为string类型
       Func<int, string> func_2 = Show_2;
       string b = func_2(100);
       Debug.Log(b);
       // 抛出异常FormatException: Input string was not in a correct format.
       /*Func<string, int > func_3 = Show_3;
       int c = func_3("s");
       Debug.Log(c);*/
  }
   string Show_1()
  {
       return "Show_1";
  }
   String Show_2(int a)
  {
       return a.ToString();
  }
   int Show_3(string x)
  {
       return int.Parse(x);
  }
}

 

4. 匿名方法、event事件、多播委托

匿名方法:没有名字的方法称之为匿名方法。

Event事件:Event事件本身就是一种委托,只是该委托只能作为类的成员,且不可在类外进行调用。

多播委托:在 C# 语言中,多播委托是指在一个委托中注册多个方法,在注册方法时可以在委托中使用加号运算符或者减号运算符来实现添加或撤销方法。

/**
* 1. 匿名事件
* 2. event事件
* (1)event事件 只允许作为类的成员变量,且仅在类的内部使用才可以,外部不得直接调用
* (2)当作为一个类的成员,event事件在外部类赋值时,只能通过 +=/-= 的方式;而对于普通的Action则可以 =/+=/-=的方式进行赋值
* (3)可通过在类中定义方法调用event事件,外部类间接地调用这个方法来调用event
* 3. 多播委托 += -=
* 委托属于引用类型,引用类型的默认值为null,直接使用会报空异常;
* 故在使用之前需要先判断委托对象(引用对象)是否为空
*/
public class MyEventClass
{
   public event Action action_3;
   public Action action_4;

   // event事件调用
   public void Send()
  {
       if(action_3 != null)
      {
           action_3();
      }
  }
}

public class Broadcast : MonoBehaviour
{
   // event事件
   event Action action_2;

   void Start()
  {
       // Action action = Show_1; 将该语句转为匿名
       Action action = delegate ()  // 匿名函数
      {
           Debug.Log("匿名函数被执行");
      };
       action();
       // 多播委托
       Action action_1 = Show_1;
       action_1 += Show_2;
       //action_1 -= Show_2;
       //action_1 -= Show_1;
       if (action != null)
      {
           action_1();
      }

       action_2 = Show_1;
       action_2();

       MyEventClass mEvent = new MyEventClass();
       mEvent.action_3 += Show_2;
       mEvent.Send();
       mEvent.action_4 = Show_2;
       mEvent.action_4();
  }
   void Show_1()
  {
       Debug.Log("Show_1被执行");
  }
   void Show_2()
  {
       Debug.Log("Show_2被执行");
  }
}
 
posted @   Dukenone  阅读(149)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示