委托与事件
委托与事件
1、基本概念
- 委托本质是一个类,继承System.MulticastDelegate。里面有三个方法:Invoke、BeginInvoke、EndInvoke;
// 定义一个委托,可以定义到类的外面或者里面
public delegate void NoReturnNoParm();
// 和委托具有相同签名的方法
public void Say()
{
MessageBox.Show("我被调用了");
}
- 三种实例化,两种调用方法
// 实例化一个委托,new关键字 参数必须是一个和委托具有相同签名的方法
NoReturnNoParm noReturnNoParm = new NoReturnNoParm(Say);
// 实例化一个委托,lambda表达式
NoReturnNoParm noReturnNoParm1 = () => { MessageBox.Show("我是谁"); };
// 实例化一个委托,匿名方法
NoReturnNoParm noReturnNoParm2 = delegate () { MessageBox.Show("我是谁"); };
// 第一种调用
noReturnNoParm.Invoke();
// 第二种调用
noReturnNoParm();
- C#内置泛型委托
- 1、Action
只能委托必须是无返回值的方法 - 2、Fun
只是委托必须有返回值的方法,最后一个参数必须是返回值 - 3、Predicate:此委托返回一个bool值,该委托通常引用一个"判断条件函数"。需要指出的是,判断条件一般为“外部的硬性条件”,比如“大于50”,而不是由数据自身指定,如“查找数组中最大的元素就不适合”。
Action<string> _action = new Action<string>(SayHello);
_action("Hello World");
Action<string> noReturn = (s) => { MessageBox.Show($"我是{s}"); };
noReturn.Invoke("刘备");
Func<int, bool> _func = new Func<int, bool>(Check);
_func(5);
Predicate<int> _predicate = new Predicate<int>(Check);
//使用Lambda表达式
Predicate<int> predicate = p => p % 2 == 0;
_predicate(26);
// 定义一个带委托的方法
List<Student> GetAll(Func<Student,bool> act)
{
List < Student > list = new List<Student>() {
new Student(1,"刘备",1,45),
new Student(2,"诸葛亮",1,47),
new Student(3,"关羽",1,25),
new Student(4,"张飞",1,28),
new Student(5,"曹操",2,52),
new Student(6,"曹丕",2,18),
new Student(7,"司马懿",2,36),
new Student(8,"孙权",3,33),
new Student(9,"周瑜",3,26),
};
List<Student> result = new List<Student>();
foreach (var stu in list)
{
if (act(stu))
{
result.Add(stu);
}
}
return result;
}
// 调用该方法
List<Student> list = GetAll(s => { return s.Age > 40; });
- 多播委托 += -=
// 获取所有的委托
Delegate[] deles = noReturnNoParm.GetInvocationList();
2、事件
- 事件是允许类或对象的某些状态发生改变时通知其它类或对象。
- 是带event关键字的委托的实例,可以限制变量被外部调用或者赋值;即使在子类中也不能赋值或者调用,只能+=或者-=
- 遵循观察者模式,发送或引发事件的类称为发布者,接收或处理事件的类称为订阅者。
- 事件和委托的区别与联系:委托是一个类,而事件是委托的实例;
世界上没有什么事情是跑步解决不了的,如果有,那就再跑一会!