.net学习之委托和事件

 

1.什么是委托 通俗的说:委托就是一个能够存储符合某种格式(方法签名)的方法的指针的容器 上传图片:

2.委托语法 准备一个方法:string Hello(string userName){}        string Hello2(string userName){} 声明委托类:delegate string DGSayHi(string userName); 创建委托对象:DGSayHi dgSay = new DGSayHi(Hello); 或 DGSsyHi dgSay = Hello; 追加方法:dgSay+=Hello2; 删除方法:dgSay -=Hello2; 调用委托:dgSay("你好");

3.多播委托 通常将包含多个方法指针的委托叫做多播委托 其实每个用户定义的委托类型编译后都是一个继承于多播委托的类,看源码:

上传图片:

4.委托的目的 (1)能将方法作为参数和返回值传递 (2)调用一个委托,执行N个方法(多播委托)

5.委托的缺点 不进行控制的缺点:可以使用Click=null来清除所有注册的事件,可以用Click()来假冒事件的触发。 解决方案,把委托成员做成private的,然后增加AddClickEventHandler、RemoveClickEventHandler两个public方法

6.什么是事件 对委托变量的可访问性进行控制封装 语法:public delegate void DGSayHi(string name);       public event DGSayHi dgSay;//创建事件委托(本质还是委托对象) event会自动生成一个private delegate变量和两个函数: add和remove,C#编译器用这两个方法支持+=和-=操作符

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7.  
  8. namespace ConsoleApplication1
  9. {
  10. public delegate void DGEach(int index,object item);
  11. public delegate void DGTest();
  12.  
  13. internal class Program
  14. {
  15. public static void Test1(DGTest dgTest)
  16. {
  17. dgTest(); //编译后:dgTest.Invoke();
  18. Console.WriteLine("Test1");
  19. }
  20.  
  21. public static void Test2()
  22. {
  23. Console.WriteLine("Test2");
  24. }
  25.  
  26. public static void Test3()
  27. {
  28. Console.WriteLine("Test3");
  29. }
  30.  
  31. /// <summary>
  32. /// 委托当返回值
  33. /// </summary>
  34. /// <param name="strType"></param>
  35. /// <returns></returns>
  36. public static DGTest InvokeTest(string strType)
  37. {
  38. switch (strType)
  39. {
  40. case "2":
  41. return Test2;
  42. case "3":
  43. return Test3;
  44. default:
  45. return Test3;
  46. }
  47. }
  48.  
  49. /// <summary>
  50. /// 使用委托模仿jQuery each方法
  51. /// </summary>
  52. /// <param name="list"></param>
  53. /// <param name="func"></param>
  54. public static void Each(ArrayList list, DGEach func)
  55. {
  56. for (int i = 0; i < list.Count; i++)
  57. {
  58. func(i, list[i]);
  59. }
  60. }
  61.  
  62. private static void Main(string[] args)
  63. {
  64. #region 委托当参数
  65.  
  66. //DGTest dgTest = new DGTest(Test2);//或者 DGTest dgTest = Test2;
  67. //Test1(dgTest);
  68.  
  69. #endregion
  70.  
  71. #region 委托当返回值
  72.  
  73. //DGTest dgTest = InvokeTest("2");
  74. //dgTest();
  75.  
  76. #endregion
  77.  
  78. #region 完成 Each方法
  79.  
  80. //ArrayList list = new ArrayList();
  81. //list.Add("刘德华");
  82. //list.Add("张学友");
  83. //list.Add("郭富城");
  84. //list.Add("黎明");
  85. // Each(list, delegate(int index,object item)
  86. // {
  87. // Console.WriteLine(index+"---------"+item.ToString());
  88. // });
  89.  
  90. #endregion
  91.  
  92. #region 事件练习,一个设计模式的题目,说有三个对象,猫,老鼠,人,猫看见了老鼠,老鼠吓跑了,在过程中把人吵醒, 在编程过程中注意新的对象的参与
  93. Cat c = new Cat();
  94. c.Name = "tom";
  95. c.DGRunEventHandler += c_DGRunEventHandler;
  96. c.SeeMouse(c.Name);
  97. #endregion
  98. }
  99.  
  100. private static void c_DGRunEventHandler(object sender,EventArgs e)
  101. {
  102. Mouse m = new Mouse();
  103. m.Name = "mouse1";
  104. m.DGRunEventHandler += m_DGRunEventHandler;
  105. m.MouseRun(m);
  106. }
  107.  
  108. private static void m_DGRunEventHandler(object sender, EventArgs e)
  109. {
  110. Person p = new Person();
  111. p.WakeUp(sender);
  112. }
  113. }
  114.  
  115. public class Cat
  116. {
  117. public event EventHandler DGRunEventHandler;
  118. public void SeeMouse(string name)
  119. {
  120. Console.WriteLine(name+"看见老鼠");
  121. if (DGRunEventHandler != null)
  122. {
  123. DGRunEventHandler(this,new EventArgs());
  124. }
  125. }
  126.  
  127. public string Name { get; set; }
  128. }
  129. public class Person
  130. {
  131. public void WakeUp(object sender)
  132. {
  133.  
  134. Console.WriteLine((sender as Mouse).Name+"老鼠跑,人醒了");
  135. }
  136. public string Name { get; set; }
  137. }
  138.  
  139. public class Mouse
  140. {
  141. public event EventHandler DGRunEventHandler;
  142. public void MouseRun(object sender)
  143. {
  144. Console.WriteLine((sender as Mouse).Name+"老鼠跑");
  145. if (DGRunEventHandler != null)
  146. {
  147. DGRunEventHandler(this, new EventArgs());
  148. }
  149. }
  150. public string Name { get; set; }
  151. }
  152. }

.NET委托和事件的更多相关文章

  1. .NET面试题系列[7] - 委托与事件

    委托和事件 委托在C#中具有无比重要的地位. C#中的委托可以说俯拾即是,从LINQ中的lambda表达式到(包括但不限于)winform,wpf中的各种事件都有着委托的身影.C#中如果没有了事件,那 ...

  2. .NET基础拾遗(4)委托、事件、反射与特性

    Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理基础 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开 ...

  3. [转载]C#深入分析委托与事件

    原文出处: 作者:风尘浪子 原文链接:http://www.cnblogs.com/leslies2/archive/2012/03/22/2389318.html 同类链接:http://www.c ...

  4. [转载]C#委托和事件(Delegate、Event、EventHandler、EventArgs)

    原文链接:http://blog.csdn.net/zwj7612356/article/details/8272520 14.1.委托 当要把方法作为实参传送给其他方法的形参时,形参需要使用委托.委 ...

  5. C#委托与事件

    一.在控制台下使用委托和事件 我们都知道,C#中有"接口"这个概念,所谓的"接口"就是定义一套标准,然后由实现类来具体实现其中的方法,所以说"接口,是 ...

  6. C#委托与事件的简单使用

    前言:上一篇博文从原理和定义的角度介绍了C#的委托和事件.本文通过一个简单的小故事,来说明C#委托与事件的使用方法及其方便之处. 在阅读本文之前,需要你对委托和事件的基本概念有所了解.如果你是初次接触 ...

  7. C#之委托与事件

    委托与事件 废话一堆:网上关于委托.事件的文章有很多,一千个哈姆雷特就有一千个莎士比亚,以下内容均是本人个人见解. 1. 委托 1.1 委托的使用 这一小章来学习一下怎么简单的使用委托,了解一些基本的 ...

  8. [ASP.NET MVC 大牛之路]02 - C#高级知识点概要(1) - 委托和事件

    在ASP.NET MVC 小牛之路系列中,前面用了一篇文章提了一下C#的一些知识点.照此,ASP.NET MVC 大牛之路系列也先给大家普及一下C#.NET中的高级知识点.每个知识点不太会过于详细,但 ...

  9. C#委托和事件

    委托和事件都可以用来调用跟自己方法签名一样的方法,两者在使用中主要有以下区别: 委托和事件没有可比性,因为委托是类型,事件是对象: 委托可以在声明它的类外部进行调用,而事件只能在类的内部进行调用: 委 ...

随机推荐

  1. 【超级干货】手机移动端WEB资源整合

    meta基础知识 H5页面窗口自动调整到设备宽度,并禁止用户缩放页面 <meta name="viewport" content="width=device-wid ...

  2. Javascript的shift()和push(),unshift()和pop()方法简介

    栈方法: Javascript为数组专门提供了push()和pop()方法,以便实现类似栈的行为.来看下面的例子: var colors=new Array();       //创建一个数组 var ...

  3. 基于jquery上的轻量级《数据模板解析》插件

    1.先上一个栗子. <!doctype html> <html lang="en"> <head> <meta charset=" ...

  4. js中==和===的区别

    ==用来判断值是否相等: ===用来判断值和类型是否相等

  5. Python3中使用PyMySQL连接Mysql

    Python3中使用PyMySQL连接Mysql 在Python2中连接Mysql数据库用的是MySQLdb,在Python3中连接Mysql数据库用的是PyMySQL,因为MySQLdb不支持Pyt ...

  6. springboot+redis

    上篇整合了DB层,现在开始整合缓存层,使用redis. springboot驱动注解,使用spring注入JedisPool便可封装自己的redis工具类. package hello.configu ...

  7. PHP 使用 password_hash() 给密码加密

    PHP >= 5.5 时,可以使用 password_hash() 和 password_verify() 来对用户的密码进行加密和验证,例如在用户注册(加密存储)和登陆(验证): <?p ...

  8. Servlet生命周期引起的问题

    A:Servlet的定义与作用. B:Serlvet的体系结构 Servlet | | GenericServlet | | HttpServlet | | 用户自定义的Servlet. HttpSe ...

  9. MyEclipse 快捷键

    MyEclipse 快捷键1(CTRL) Ctrl+1 快速修复Ctrl+D: 删除当前行Ctrl+Q 定位到最后编辑的地方Ctrl+L 定位在某行Ctrl+O 快速显示 OutLineCtrl+T ...

  10. [翻译]类型双关不好玩:C中使用指针重新解释是坏的

    原文地址 Type punning isn't funny: Using pointers to recast in C is bad. C语言中一个重新解释(reinterpret)数据类型的技巧有 ...