c#之委托事件(DelegateEvent)
前面一章学习了委托以及多播委托,接下来我们来学习下委托事件。
在学习委托事件的前提下,得知道什么是观察者模式。
首先,我们来模拟一个场景:例如,当一只狗汪汪汪叫的时候,baby被吓哭了,刚好要偷东西的小偷被吓跑了。
我们一惯的思维是:创建三个类,分别写一个方法表示他们的动作,当狗叫的时候,分别调用。代码如下:
public class Dog
{
public static void Wang()
{
Console.WriteLine("狗汪汪汪汪");
Baby.Cry();
Thief.Run();
}
}
public class Baby
{
public static void Cry()
{
Console.WriteLine("baby被吓哭了");
}
}
public class Thief
{
public static void Run()
{
Console.WriteLine("小偷跑了");
}
}
class Program
{
static void Main(string[] args)
{
Dog.Wang(); Console.Read();
}
}
这样做是可以得到我们想要的结果,但是,Dog类与Baby、Thief之间的耦合就很紧了,不利于后期维护扩展。当我们后期需求变动,要再添加一个动作:猫也被吓的跑掉了。
怎么办,难道我们还要去改动Dog类里Wang方法的代码嘛?这明显是一个糟糕的事情。不过总是有办法解决的,毕竟办法都是人想出来的。
上一个章节我们知道了多播委托,就是把多个方法绑定到同一个委托,然后依次执行。
接下来我们来看看怎么实现。
1、首先我们得声明一个委托,并且创建这个委托的实例。
2、当狗叫的时候,我们来调用这个委托。
3、当我们调用狗叫之前,将要触发的一系列动作(也就是观察者的动作)绑定到委托就行了。
这3个步骤的代码如下:
public delegate void DogWang();
public class Dog
{
static DogWang DogWangHandler;
public static void Wang()
{
Console.WriteLine("狗汪汪汪汪"); if (DogWangHandler != null)
DogWangHandler.Invoke();
}
}
class Program
{
static void Main(string[] args)
{
Dog.DogWangHandler = new DogWang(Baby.Cry);
Dog.DogWangHandler += Thief.Run; Dog.Wang(); Console.Read();
}
}
贴一下结果吧。

没毛病。讲到这里,恍然大悟了,这样的话,我们后需求添加多少个动作都没关系,我们只需要将方法绑定(+=)给委托就行。当然也是可以取消(-=)某一个动作的。
接下来我们就要开始讲事件了,
那么什么是事件呢?什么是委托呢,它们之前又是什么关系呢?我想这个问题肯定有很多人想知道,也有很多人搞不清楚。
我们知道委托是一种类型,而事件就是委托一个实例 。其实就是这么简单的。
我们将上面的代码用事件来实现,看看是什么样的。
public delegate void DogWang();
public class Dog
{
public static DogWang DogWangHandler;
public static event DogWang DogWangHandlerEvent;//事件的本质就是委托的一个实例。加了event关键字
public static void Wang()
{
Console.WriteLine("狗汪汪汪汪"); if (DogWangHandlerEvent != null)
DogWangHandlerEvent.Invoke();
}
} class Program
{
static void Main(string[] args)
{
Console.WriteLine("==============事件实现================");
Dog.DogWangHandlerEvent += Baby.Cry;
Dog.DogWangHandlerEvent += Thief.Run;
Dog.Wang(); Console.Read();
}
}
结果如下:

结果和上面一样,这是就委托事件。那么委托与事件调用有什么不一样呢?
1、事件不能像委托一样 Dog.DogWangHandler = new DogWang(Baby.Cry); 被这样初始化。因为委托可以 Dog.DogWangHandler = null; ,用事件是为了不能在外部随随便便地将委托给 null 。
2、事件不能像委托一样在外部调用 Dog.DogWangHandler(); ,这样是为了调用者不能想调用就调用。为了防止当触发一个件事,执行到一部分的时候就来调用。
小结一下:其实它们之前的区别就是一个权限问题。
c#之委托事件(DelegateEvent)的更多相关文章
- C# ~ 从 委托事件 到 观察者模式 - Observer
委托和事件的部分基础知识可参见 C#/.NET 基础学习 之 [委托-事件] 部分: 参考 [1]. 初识事件 到 自定义事件: [2]. 从类型不安全的委托 到 类型安全的事件: [3]. 函数指针 ...
- C#委托,事件理解入门 (译稿)
原文地址:http://www.codeproject.com/Articles/4773/Events-and-Delegates-Simplified 引用翻译地址:http://www.cnbl ...
- 关于ios使用jquery的on,委托事件失效
$('.parents').on("click",'.child',function(){}); 类似上面这种,在ios上点击"child"元素不会起作用,解决 ...
- Observer设计模式中-委托事件-应用在消息在窗体上显示
Observer设计模式:监视者模式.在类中的方法中处理的结果或者消息通过事件委托 的方式发送给主窗体. 因为在其它类中直接访问主窗体类,显示内容是不能直接调用控件赋值的,当然也有别的类似查阅控件名, ...
- Asp.net用户控件和委托事件
在Asp.net系统制作过程中,门户类型的网站,我们可以用DIV+CSS+JS+Ajax全部搞定,但是一旦遇到界面元素比较复杂的时候,还是UserControl比较方便一些,各种封装,各种处理,然后拖 ...
- jQuery里面的普通绑定事件和on委托事件
以click事件为例: 普通绑定事件:$('.btn1').click(function(){}绑定 on绑定事件:$(document).on('click','.btn2',function(){ ...
- c#基础学习笔记-----------委托事件
这里有一个比较简单的委托实例应用(跨窗体操作控件) http://blog.csdn.net/bdstjk/article/details/7004035 还有一个比较详细的介绍并深入理解委托事件的讲 ...
- c#委托事件入门--第二讲:事件入门
上文 c#委托事件入门--第一讲:委托入门 中和大家介绍了委托,学习委托必不可少的就要说下事件.以下思明仍然从事件是什么.为什么用事件.怎么实现事件和总结介绍一下事件 1.事件是什么:. 1.1 NE ...
- Unity C#笔记 委托&事件
C#的委托与事件搭配,即是观察者模式的一种实现. 因为观察者模式的原理很易懂,不作多讲,本文纯粹用于记录语法. delegate(委托) //声明没有参数,没有返回值的委托类型XXXX public ...
随机推荐
- Java 8学习之Lambda表达式
一.lambda表达式 一个lambda表达式包含三个部分: 一段代码 参数 自由变量的值,这里的自由指的是哪些不是参数并且没有在代码中定义的变量. 示例: public static void re ...
- 第3章—高级装配—配置profile bean
配置profile bean 3.1.@profile注解是spring提供的一个用来标明当前运行环境的注解. 我们正常开发的过程中经常遇到的问题是,开发环境是一套环境,qa测试是一套环境,线上部署又 ...
- jmeter笔记
Jmeter性能测试 入门 Jmeter 录制脚本:使用一个叫badbody的工具录制脚步供jmeter使用,http://www.badboy.com.au/:也可以用jmeter来录制 Jmete ...
- ELK系列~Fluentd对大日志的处理过程~16K
Fluentd是一个日志收集工具,有输入端和输出端的概念,前者主要是日志的来源,你可以走多种来源方式,http,forward,tcp都可以,后者输出端主要指把日志进行持久化的过程,你可以直接把它持久 ...
- 何为session?
何为session 在计算机中,尤其是在网络应用中,称为"会话控制".session 对象存储特定用户会话所需的属性及配置信息.这样,当用户在应用程序的 Web 页之间跳转时,存储 ...
- 前端自动化Gulp工具常用插件
npm init命令初始化当前文件夹后,在当前文件夹新建gulpfile.js文件.当前目录下的所有操作流都在gulpfile.js文件中定义. gulp自动化 gulp-uglify (JS压缩) ...
- C/C++编码规范
C/C++编码规范 今天人们越来越明白软件设计更多地是一种工程,而不是一种个人艺术.由于大型产品的开发通常由很多的人协同作战,如果不统一编程规范,最终合到一起的程序,其可读性将较差,这不仅给代码的理解 ...
- LOJ #6022. 重组病毒
Description 支持以下操作 1.access一个点 2.问一个点上面的重链的个数 3.换根 , 并access原来的根 Solution 对于重链个数 , 我们在 \(access\) 的时 ...
- [转]OData的初步认识 OData v4 Client Code Generator
本文转自:http://www.cnblogs.com/1zhk/p/5356053.html What – OData是什么? OData - Open Data Protocol,是一个设计和使用 ...
- 【转】Java面试题全集(上)
准备从C#转java,在找工作之前准备看看面试题,有幸看到大神的作品,mark一下,以后慢慢看... 2013年年底的时候,我看到了网上流传的一个叫做<Java面试题大全>的东西,认真的阅 ...