C# 委托和事件
2016-07-27 21:50
459 查看
1.委托/delegate
类似于C++中的函数指针(一个指向内存位置的指针)。委托是C#中类型安全的,可以订阅一个或多个具有相同签名方法的函数指针。简单理解,委托是一种可以把函数当做参数传递的类型。很多情况下,某个函数需要动态地去调用某一类函数,这时候我们就在参数列表放一个委托当做函数的占位符。
在某些场景下,使用委托来调用方法能达到减少代码量,实现某种功能的用途。
1.1 自定义委托
声明和执行一个自定义委托,大致可以通过如下步骤完成:1.利用关键字delegate声明一个委托类型,它必须具有和你想要传递的方法具有相同的参数和返回值类型;
2.创建委托对象,并且将你想要传递的方法作为参数传递给委托对象;
3.通过上面创建的委托对象来实现该委托绑定方法的调用
1.2 多薄委托
一个委托可以引用多个方法,包含多个方法的委托就叫多播委托。多播委托的声明过程是和自定义委托一样的,可以理解为,多播委托就是自定义委托在实例化时通过 “+=” 符号多绑定了两个方法。
“+=”的本质是调用了Delegate.Combine方法,该方法将两个委托连接在一起,并返回合并后的委托对象。
class Program { //1.使用delegate关键字声明委托 private static void EnglishGreeting(string name) { Console.WriteLine("Morning." + name); } private static void ChineseGreeting(string name) { Console.WriteLine("早上好." + name); } //它接受一个GreetingDelegate类型的方法作为参数 private static void GreetPeople(string name, GreetingDelegate MakeGreeting) { MakeGreeting(name); } static void Main(string[] args) { //GreetPeople("J-Will", EnglishGreeting); //GreetPeople("张三", ChineseGreeting); //Console.ReadKey(); /* GreetingDelegate delegate1; delegate1 = EnglishGreeting;// 先给委托类型的变量赋值 delegate1 += ChineseGreeting;// 给此委托变量再绑定一个方法 delegate1("j will"); GreetPeople("j will", delegate1);// 将先后调用 EnglishGreeting 与 ChineseGreeting 方法 */ //2.实例化这个委托,并引用方法 GreetingDelegate dlg_1 = new GreetingDelegate(EnglishGreeting); //简写为: GreetingDelegate dlg_1 = EnglishGreeting; dlg_1 += ChineseGreeting; // += : 给此委托变量再绑定一个方法(多播) dlg_1("j will"); Console.ReadKey(); Console.WriteLine("______分隔______"); dlg_1 -= ChineseGreeting; // -= : 取消对EnglishGreeting方法的绑定 dlg_1("j will"); } }
对于有返回值的方法需要我们从委托列表上手动调用。否则,就只能得到委托调用的最后一个方法的结果。
正确做法:利用GetInvocationList获得委托列表上所有方法,循环依次执行委托,并处理委托返回值。
//获取委托链上所有方法 Delegate[] delList = del.GetInvocationList(); //遍历,分别处理每个方法的返回值 foreach (GetStrDelegate item in delList) { //执行当前委托 string result = item(); Console.WriteLine(result); //控制台输出结果: //You called me from Func1 //You called me from Func2 //You called me from Func3 } Console.ReadKey();
1.3 匿名方法
简化委托的声明。假如委托引用的方法只使用一次,那么就没有必要声明这个方法,这时用匿名方法表示即可。GreetingDelegate dlg_1 = delegate(string str) { return str.ToUpper(); }; //直接在签名中写方法内容 string result = dlg_1 ("KaSlFkaDhkjHe");
通常在下面情况下使用:
1.委托需要指定一个临时方法,该方法使用次数极少;
2.这个方法的代码很短,甚至可能比方法声明都短的情况下使用。
1.4 内置委托
微软直接把定义委托这一步骤封装好,形成三个泛型类:Action、Func和Predicate,省去了定义的步骤。public class Program { public static void Main(string[] args) { //Action Action<string> action = delegate(string str) { Console.WriteLine("你好!" + str); }; action("GG"); //Func Func<int, int, int> func = delegate(int x, int y) { return x + y; }; Console.WriteLine("计算结果:" + func(5, 6)); //Predicate Predicate<bool> per = delegate(bool isTrue) { return isTrue == true; }; Console.WriteLine(per(true)); } }
Action委托:允许封装的方法有多个参数,不能有返回值;
Func委托:允许封装的方法有多个参数,必须有返回值;
Predicate委托:允许封装的方法有一个参数,返回值必须为bool类型。
2.事件/event
委托是一种类型,事件依赖于委托,故事件可以理解为是委托的一种特殊实例。委托可以在任意位置定义和调用,但是事件只能定义在类的内部,只允许在当前类中调用。所以说,事件是一种类型安全的委托。
本文绝大部分转自http://www.cnblogs.com/gao-yang/p/5493028.html,感谢博主gao-yang。
相关文章推荐
- c#调用COM组件
- C#实现把指定数据写入串口
- C#动态创建button的方法
- C#中抽象方法与虚拟方法的区别
- c#中虚函数的相关使用方法
- C#实现给图片加水印的方法
- C#使用加边法计算行列式的值
- C#实现多线程的同步方法实例分析
- jQuery中的常用事件总结
- C#中尾递归的使用、优化及编译器优化
- C#中的delegate委托类型基本学习教程
- C#实现子窗体与父窗体通信方法实例总结
- C#通用邮件发送类分享
- 举例讲解C#中自动实现的属性
- C#中this的用法集锦
- C#数据结构之顺序表(SeqList)实例详解
- C#.NET获取拨号连接的宽带连接方法
- C#异步绑定数据实现方法
- C#实现AddRange为数组添加多个元素的方法
- JavaScript—事件