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

  • Post author:
  • Post category:其他




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>

    表示有传入参数

    int



    string

    无返回值的委托;

  • Action<int, string, bool>

    表示有传入参数

    int



    string



    bool

    无返回值的委托;

  • 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>

    表示传入参数为

    object



    string

    ,返回值类型为

    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被执行");
    }
}



版权声明:本文为Dukenone原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。