C#_委托/事件碎碎念

1.委托和事件的关系

委托之于事件,相当于字段之于属性
事件本质上就是对多播委托的语法和访问级别上的封装,其主要作用是:

  • 限制访问:外部代码不能直接调用事件(只能 += / -=)
  • 仅允许通过 +=(订阅)和 -=(取消订阅)的方式管理回调;
  • 隐藏委托对象的调用权。

2.委托/事件+=和-=的本质

委托:定义委托类型 -> 声明委托变量 -> 将委托实例赋值给委托变量

delegate void Calculate(int x, int y); // 声明委托类型


public static void add(int x, int y)
{
    Console.WriteLine("add=" + (x + y));
}
 
public static void sub(int x, int y)
{
    Console.WriteLine("sub=" + (x - y));
}

Calculate calculate; // 声明委托变量
calculate += add;    // 将委托实例赋值给委托变量
calculate += sub;    // 将委托实例赋值给委托变量

但实际上 += 在此处属于语法糖,本质上是:

calculate = (Calculate)Delegate.Combine(calculate, new Calculate(add));

事件:声明事件(event关键字 + 委托类型)变量 -> 将委托实例赋值给事件变量
本质同上:

SomethingHappened += new EventHandler(SomeMethod);

_somethingHappened = (EventHandler)Delegate.Combine(_somethingHappened, new EventHandler(SomeMethod));

3.传参问题

无参异步委托传入有参异步委托:
为Func<Task>形参传入Func<Task<T>>委托,可以执行,编译器会将其封装为Func<Task>,但是无法获取返回值T

同步委托传入异步委托:
无法为Func<T>传入异步委托:异步委托无论是返回void,Task或Task<T>,都不可转换为Func<T>
部分情况下可以为Action传入异步委托:异步函数返回值为void时符合条件(只是此时的异步函数是"以同步方式运行的异步函数",无意义),为Task时Task会被隐式遗弃,为Task<T>时无法编译通过(Task<T>无法隐式遗弃,而Action不接受返回值),所以当异步委托返回值为void或Task时可以将其传入给Action

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值