c# 优化代码的一些规则——用委托表示回调[五]
前言
委托为什么可以作为回调?
因为委托可以作为方法的参数。
正文
通过委托,是一种定义类型安全回调。
记得第一个接触委托的时候,是老师讲的,后来真正用的是完成学期项目,一个winform,委托作为事件处理,怀念写客户端的日子。
很多时候我们通过接口来对类与类之间解耦,但是委托是一种比接口耦合还要低的解耦方式,我不需要知道你,你也不需要知道我,因为各自只需要听到对方的声音(监听回调)。
通常情况下,我们只需要订阅好事件,然后相应的类触发即可,至于谁绑定了,触发者是不需要知道的。
在c#,漫长的迭代中,终于出现了委托神器,Action<>与Function<>还有predicate。
predicate其实就是Fuction<T,bool>,只是太普遍使用单独分出来。
在c# 中很多函数都是利用了委托实现:
看下一些例子:
static void Main(string[] args)
{
var numbers=Enumerable.Range(1, 200).ToList();
var oddNumbers = numbers.Find(n => n / 2 == 1);
}
通过反编译我们得知:
int num = Enumerable.ToList<int>(Enumerable.Range(1, 200)).Find(delegate (int n) {
return (n / 2) == 1;
});
编译器为我们做了优化,因为这个numbers 优化了一下,不过这不是重点了。
在find 中就是使用了委托:
public T Find(Predicate<T> match)
{
throw null;
}
一般来说就是遍历,通过match进行判断,然后返回一个新的list。
委托回调虽然好用,且安全,但是也有坑。
比如说多播委托,多播委托作为回调有两个需要注意的地方:
1.程序在执行这些目标函数的过程中会发生异常。
2.程序会把最后执行函数作为返回结果。
针对多播委托,可以这么写:
加入有一个委托为 Func<Student,bool> pred
bool valdate=true;
for(Func<Student,bool> pr in pred.GetInvocationList())
{
valdate = pr(student);
if(!valdate)
{
break;
}
}
把多播遍历出来即可。
上面是手写的,所以不保证语句正确,只是简单思路。
总结
值得注意的只有多播函数了,其他的希望道友补充。