委托

  1. 委托: 将一个函数作为另一个函数的参数,可以把方法当成变量一样传来传去,用来回调、解耦代码、实现事件机制。
声明委托
$$ \underbrace{\text{delegate }}_{\text{关键字}} \underbrace{\text{ void}}_{\text{返回类型}} \underbrace{\text{ AnimalPlay }}_{\text{委托名称}} \underbrace{\text{(string }}_{\text{参数类型}} \text{ name)} $$
委托在函数中的位置
$$ \text{static void CircusStart(} \underbrace{\text{AnimalPlay }}_{\text{委托类型}} \underbrace{\text{ animalplay}}_{\text{委托}} \text{, string name)} $$
  • 委托是引用类型, 委托有“引用”和“对象”两个概念, 委托类型必须在使用前声明.
  • 委托声明与方法声明相似, 只是没有实现块. 委托不需要在类内部声明.
  • 委托可以看成一个包含有序方法列表的对象, 其包含的方法具有相同的签名和返回类型.

委托示例

没有参数和返回值的委托类型
调用带返回值的委托
调用带引用参数的委托
using System;

/**
 * 定义一个没有参数和返回值的委托类型
 * PrintFunction(): 签名
 */
delegate void PrintFunction();

class Test {
    public void Print1() {
        Console.WriteLine("调用实例方法");
    }
    public static void Print2() {
        Console.WriteLine("调用静态方法");
    }
}

public class main {
	public static void Main() {
        Test t = new Test();
        // 创建委托引用并赋值
        PrintFunction pf = t.Print1;
        // 绑定,在使用 += 前要先使用 = 赋值.
        // 如果取消对方法的绑定,使用 -= 运算符.
        pf += Test.Print2;
        pf += t.Print1;
        if (null != pf)
            // 调用委托
            pf();
        else
            Console.WriteLine("委托没有方法列表");
	}
}
using System;

/**
 * 定义一个带有返回值的委托类型
 * PrintFunction(): 签名
 */
delegate int PrintFunction();

class Test {
    int IntValue = 5;
    public int Add1() {
        IntValue += 1;
        return IntValue;
    }
    public int Add2() {
        IntValue += 2;
        return IntValue;
    }
}

public class main {
	public static void Main() {
        Test t = new Test();
        // 创建委托引用并赋值
        PrintFunction pf = t.Add1;
        // 绑定,在使用 += 前要先使用 = 赋值.
        // 如果取消对方法的绑定,使用 -= 运算符.
        pf += t.Add1;
        pf += t.Add2;
        pf += t.Add1;
        Console.WriteLine($"Value: { pf() }");
	}
}
using System;

/**
 * 定义一个带有引用参数的委托类型
 * PrintFunction(): 签名
 */
delegate void PrintFunction(ref int x);

class Test {
    public void Add1(ref int x) {
        x += 1;
    }
    public void Add2(ref int x) {
        x += 2;
    }
}

public class main {
	public static void Main() {
        Test t = new Test();
        // 创建委托引用并赋值
        PrintFunction pf = t.Add1;
        // 绑定,在使用 += 前要先使用 = 赋值.
        // 如果取消对方法的绑定,使用 -= 运算符.
        pf += t.Add1;
        pf += t.Add2;
        int x = 5;
        pf(ref x);
        Console.WriteLine($"Value: { x }");
	}
}

事件

事件本质上是:

一种只能由类内部触发(raise),但可以由外部订阅(+=)或取消订阅(-=)的委托。

换句话说:

外部代码 可以订阅事件

外部代码 不能随意触发事件

事件只能由 事件拥有者 触发

+ 在线测试

链接

  1. C#委托与事件