本文介绍event的使用以及原理,本文接上一篇文章的Demo继续【下载上一篇Demo

上一篇我们在类(dg_SayHi.cs)里面定义代理了4个Delegate,然后在Button的后台事件中 新建委托对象并初始化,这样去使用委托。本文我们看一下event的使用以及原理.

1,现在我们在Person类里面 定义一个dg_SayHi委托变量,这样新建person类对象后就可以操作这个委托变量

  A,Person类添加委托变量

 public class Person
{
#region 姓名
string name; public string Name
{
get { return name; }
set { name = value; }
}
#endregion #region 年龄
int age; public int Age
{
get { return age; }
set { age = value; }
}
#endregion //定义委托变量
public dg_SayHi dgSayHi; }

  B,添加按钮btnPerson以及btnPersonDelegate_Click事件,事件中我们使用委托对象

  private void btnPersonDelegate_Click(object sender, EventArgs e)
{
Person per = new Person(); //创建委托对象并赋值给person对象的dgSayHi对象
per.dgSayHi = new dg_SayHi(SayHiCN);
per.dgSayHi += SayHiEN; //调用委托对象
per.dgSayHi();
}

  C,这样点击按钮的时候,调用SayHiCN和SayHiEN方法,分别先后弹出窗口 “你好上海” 和 “hi shanghai”。

  D,由于是直接操作委托对象dgSayHi, 这样就可以直接把添加过方法的委托对象给清空或者重置,我们更新button后台事件如下:

     private void btnPersonDelegate_Click(object sender, EventArgs e)
{
Person per = new Person(); //创建委托对象并赋值给person对象的dgSayHi对象
per.dgSayHi = new dg_SayHi(SayHiCN);
per.dgSayHi += SayHiEN; //下面的代码把之前添加在委托里的方法给清空了,然后把委托对象给重置了
per.dgSayHi = null;
per.dgSayHi = new dg_SayHi(SayHiEN); //调用委托对象
per.dgSayHi();
}

  E,上面这样,委托对象在运行的过程中就会被不合理清空掉,这样是不安全的。

2,为了对委托对象的操作进行限制,我们把委托对象定义为私有,然后添加像属性一样的操作委托对象的方法

  A,更新Person类,把委托变为私有,并添加操作私有变量的方法

  public class Person
{
#region 姓名
string name; public string Name
{
get { return name; }
set { name = value; }
}
#endregion #region 年龄
int age; public int Age
{
get { return age; }
set { age = value; }
}
#endregion #region 实现对委托变量的保护
//定义委托变量
private dg_SayHi dgSayHi; public void AddMethod(dg_SayHi Para_dgSayHi)
{
dgSayHi += Para_dgSayHi;
} public void RemoveMethod(dg_SayHi Para_dgSayHi)
{
dgSayHi -= Para_dgSayHi;
} public void PrintMethod()
{
dgSayHi();
}
#endregion
}

  B,这样,我们就不能直接操作委托对象了,只有借助类似属性的两个方法去给委托对象添加、移除方法,更新Button事件如下:

     private void btnPersonDelegate_Click(object sender, EventArgs e)
{
Person per = new Person(); per.AddMethod(SayHiCN);
per.AddMethod(SayHiEN);
per.PrintMethod();
}

  C,上面这样我们无法直接操作委托对象,从而实现了对委托对象的保护。

3,实际上.net的event帮我们做好了像步骤2一样的封装,从而实现对委托对象的保护

  A,我们在Person类中再次添加event声明的委托如下:

     //定义事件,实现和上面的封装一样的功能
public event dg_SayHi dgSayHiByEvent; public void PrintMethodEvent()
{
dgSayHiByEvent();
}

  B,button后台事件中,我们对委托对象的操作也就只能去添加移除方法、而不能去清空或者New,如下:

      private void btnPersonDelegate_Click(object sender, EventArgs e)
{
Person per = new Person(); ////创建委托对象并赋值给person对象的dgSayHi对象
//per.dgSayHi = new dg_SayHi(SayHiCN);
//per.dgSayHi += SayHiEN;
////下面的代码把之前添加在委托里的方法给清空了,然后把委托对象给重置了
//per.dgSayHi = null;
//per.dgSayHi = new dg_SayHi(SayHiEN); per.dgSayHiByEvent += SayHiCN; //事件实现了对委托对象的保护,可以+=、-=;但是不能再像上面初始化或者是清空
per.dgSayHiByEvent += SayHiEN; //不可以直接调用委托对象,而是通过对象的方法调用;不可以这样写: per.dgSayHiByEvent();
per.PrintMethodEvent(); }

  C,.NET Reflector中我们查看一下,我们加event的委托,实际上是 1,创建了Private dgSayHiByEvent 委托对象  2, event事件中添加了两个方法:add和remove方法;这两个方法去操作Private dgSayHiByEvent委托对象。(和set,get类似)

  

  D,所以event关键字本质就是做了两个事情,从而实现对委托对象的保护:

    1,创建了一个对应的Private委托对象

   2,然后添加Add和Remove方法访问、操作这个Private委托对象。

  

4,委托和事件的对比:

  A, 委托是类,只定义委托对象的话,没法实现对委托对象的保护,外部可以清空和新建

  B, 事件是委托对象,事件自身实现了对委托对象的保护,并提供了供外部访问的两个方法

  C,事件只能对add,remove自己,不能赋值。事件只能"注册自己 += " , “注销自己 -= ” 不能=,外界不可以注销其他注册者,外界不可以主动触发事件。

本文Demo下载

【.NET基础】--委托、事件、线程(2)的更多相关文章

  1. c#基础学习笔记-----------委托事件

    这里有一个比较简单的委托实例应用(跨窗体操作控件) http://blog.csdn.net/bdstjk/article/details/7004035 还有一个比较详细的介绍并深入理解委托事件的讲 ...

  2. C# 基础 - 委托、事件

    1. 委托 sequenceDiagram 方法->>委托: 返回值和入参一样 委托->>方法: 调用委托就是调用绑定的方法 delegate int NumTest(int ...

  3. [.net 面向对象编程基础] (22) 事件

    [.net 面向对象编程基础] (22)  事件 事件(Event)是学习.net面向对象编程很重要的一部分,在学习事件之前,我们实际上已经在很多地方使用了事件,比如控件的click事件等,这些都是. ...

  4. C# ~ 从 委托事件 到 观察者模式 - Observer

    委托和事件的部分基础知识可参见 C#/.NET 基础学习 之 [委托-事件] 部分: 参考 [1]. 初识事件 到 自定义事件: [2]. 从类型不安全的委托 到 类型安全的事件: [3]. 函数指针 ...

  5. 谈.Net委托与线程——解决窗体假死

    转自:http://www.cnblogs.com/smartls/archive/2011/04/08/2008981.html#2457370   引言 在之前的<创建无阻塞的异步调用> ...

  6. C#基础知识回顾--线程传参

    C#基础知识回顾--线程传参 在不传递参数情况下,一般大家都使用ThreadStart代理来连接执行函数,ThreadStart委托接收的函数不能有参数, 也不能有返回值.如果希望传递参数给执行函数, ...

  7. SQL Server 扩展事件(Extented Events)从入门到进阶(2)——在GUI中创建基础扩展事件

    本文属于 SQL Server 扩展事件(Extented Events)从入门到进阶 系列 第一篇文章中提到了如何在Profiler中创建跟踪(trace),并以服务器端(server-side)跟 ...

  8. C#基础委托回顾

    C#基础委托回顾 前言 快忘记了. 委托的特点 委托类似于 C++ 函数指针,但它们是类型安全的. 委托允许将方法作为参数进行传递. 委托可用于定义回调方法. 委托可以链接在一起:例如,可以对一个事件 ...

  9. C#基础之事件(2)

    在“C#基础之事件(1)”中已对事件有了一个大概,这里对事件进行更深入的学习. 本节按以下内容展开: 1.事件拥有者与事件响应者的关系: 2.事件订阅的多种写法: 3.事件的订阅和取消订阅: 4.多事 ...

  10. C# 利用委托事件进行窗体间的传值(新手必看)

    引言: 窗体间传值是每个学习WinForm新手的常见问题,最初级的方法就是 在窗体中先获取到要接受值窗体.然后通过.得到某个空间或者属性,直接赋值,这个需要接收放的窗体属性或者空间必须是public ...

随机推荐

  1. HTTP(一) 连接管理

    ・HTTP是如何使用TCP连接的 HTTP传送一条报文时,以流的形式将报文数据内容通过一条打开的TCP连接按序传输. TCP收到数据流之后,由TCP/IP软件将数据流砍成被称作段的小数据块,并将段封装 ...

  2. cocos2d_x iconv转码

    作者:何卫 转载请注明,原文链接:http://www.cnblogs.com/hewei2012/p/3374147.html iconv下载(Android) 源码下载地址,已编译完的iconv包 ...

  3. IE自动化 二(判断IP所在地)

    该脚本用来访问一个url,并取出相应结果(该脚本用来通过淘宝API实现判断一个IP所在地) #定义要访问的URL $url="http://ip.taobao.com/service/get ...

  4. java面试笔试试题http://www.jobui.com/mianshiti/it/java/6827/

    一.判断题(每题1分,共10分)1.Applet是一种特殊的Panel,它是Java Applet程序的最外层容器.()2.Java的源代码中定义几个类,编译结果就生成几个以.class为后缀的字节码 ...

  5. Java浮点值拒绝服务漏洞危害分析

    By 空虚浪子心 http://www.inbreak.net/ JAVA出了漏洞,CVE-2010-4476,会导致拒绝服务攻击.大家能从公告上,看到这样一段代码,挺长的.意思是只有开发人员写出这样 ...

  6. C++异常

    相对于C语言,C++增加了异常机制.考虑,异常解决了什么问题,又带来了什么问题. 异常解决了什么问题: 1.问题检测与问题处理相分离. 2.C语言只是返回一个整数,而异常带有上下文信息,方便找出问题. ...

  7. Codeforces Round #336 (Div. 2) C. Chain Reaction set维护dp

    C. Chain Reaction 题目连接: http://www.codeforces.com/contest/608/problem/C Description There are n beac ...

  8. codeforces Gym 100187F F - Doomsday 区间覆盖贪心

    F. Doomsday Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100187/problem/F ...

  9. 开源图形库 c语言-图形图像库 集合[转]

    开源图形库 c语言-图形图像库 集合[转] Google三维API O3D O3D 是一个开源的 Web API 用来在浏览器上创建界面丰富的交互式的 3D 应用程序.这是一种基于网页的可控3D标准. ...

  10. 我的学习笔记_Windows_HOOK编程 2009-12-03 11:19

    一.什么是HOOK? "hook"这个单词的意思是"钩子","Windows Hook"是Windows消息处理机制的一个重要扩展,程序猿能 ...