csharp委托与事件
委托
- 委托: 将一个函数作为另一个函数的参数,可以把方法当成变量一样传来传去,用来回调、解耦代码、实现事件机制。
声明委托
$$
\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),但可以由外部订阅(+=)或取消订阅(-=)的委托。
换句话说:
外部代码 可以订阅事件
外部代码 不能随意触发事件
事件只能由 事件拥有者 触发
在线测试