C#_事件委托
CarDealer类 事件发布程序
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DelegateEvent
{
public class CarInfoEventArgs : EventArgs
{
public string Car { get; private set; }
public CarInfoEventArgs(string car)
{
this.Car = car;
}
}
/// <summary>
/// 新车到达时触发的事件
/// </summary>
public class CarDealer
{
/*
* 泛型委托EventHandler<T>定义了一个处理程序,返回Void,接受两个参数
* 第一个参数必须为object,第二个参数是T类型
* T有约束,T必须派生自基类EventArgs
* 即public delegate void EventHandler<TEventArgs>(object sender,TEventArgs e)
* where TeventArgs:EventArgs
*/ public event EventHandler<CarInfoEventArgs> NewCarInfo;
public void NewCar(string car)
{
Console.WriteLine("CarDealer ,new car {0}",car);
RaiseNewCarInfo(car);
} protected virtual void RaiseNewCarInfo(string car)
{
EventHandler<CarInfoEventArgs> newCarInfo = NewCarInfo;
if (newCarInfo != null)
{
//事件一般使用带两个参数的方法,其中一个参数是对象包含事件的发送者
//第二个参数提供了事件的相关信息,第二个参数随不同的事件类型而不同
newCarInfo(this, new CarInfoEventArgs(car));
}
}
}
}
Consumer类 事件监听器
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DelegateEvent
{
/// <summary>
/// 事件订阅类
/// </summary>
class Consumer
{
private string name;
public Consumer(string name)
{
this.name = name;
} public void NewCarIsHere(object sender, CarInfoEventArgs e)
{
Console.WriteLine("{0}:car {1} is new",name,e.Car);
}
}
}
测试类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DelegateEvent
{
class Program
{
static void Main(string[] args)
{
var dealer = new CarDealer();
var michael = new Consumer("A"); //订阅者A
dealer.NewCarInfo += michael.NewCarIsHere;
dealer.NewCar("A_Car"); //A车到达 A得到通知 var sebastian = new Consumer("B"); //订阅者B
dealer.NewCarInfo += sebastian.NewCarIsHere;
dealer.NewCar("B_Car"); //B车到达 A、B都得到通知 dealer.NewCarInfo -= michael.NewCarIsHere; //A取消订阅
dealer.NewCar("C_Car"); //C车到达 只有B得到通知
}
}
}
测试结果

上述代码的不足体现在事件发布程序和事件监听器进行强连接。
添加弱事件管理器WeakCarInfoEventManager
using System.Windows; namespace DelegateEvent
{
/// <summary>
/// 弱事件管理器
/// </summary>
public class WeakCarInfoEventManager : WeakEventManager
{
/// <summary>
/// 发布程序
/// </summary>
/// <param name="source"></param>
/// <param name="listener"></param>
public static void AddListener(object source, IWeakEventListener listener)
{
CurrentManager.ProtectedAddListener(source, listener);
} /// <summary>
/// 断开发布程序
/// </summary>
/// <param name="source"></param>
/// <param name="listener"></param>
public static void RemoveListener(object source, IWeakEventListener listener)
{
CurrentManager.ProtectedRemoveListener(source, listener);
} public static WeakCarInfoEventManager CurrentManager
{
get
{
WeakCarInfoEventManager manager = GetCurrentManager(typeof(WeakCarInfoEventManager)) as WeakCarInfoEventManager;
if (manager == null)
{
manager = new WeakCarInfoEventManager();
SetCurrentManager(typeof(WeakCarInfoEventManager), manager);
}
return manager;
}
} /// <summary>
/// 订阅一个方法
/// </summary>
/// <param name="source"></param>
protected override void StartListening(object source)
{
(source as CarDealer).NewCarInfo += CarDealer_NewCarInfo;
} void CarDealer_NewCarInfo(object sender, CarInfoEventArgs e)
{
DeliverEvent(sender, e);
}
/// <summary>
/// 取消订阅一个方法
/// </summary>
/// <param name="source"></param>
protected override void StopListening(object source)
{
(source as CarDealer).NewCarInfo -= CarDealer_NewCarInfo;
}
}
}
更正事件监听器为WeakConsumer
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows; namespace DelegateEvent
{
public class WeakConsumer:IWeakEventListener
{
private string name; public WeakConsumer(string name)
{
this.name = name;
} public void NewCarIsHere(object sender, CarInfoEventArgs e)
{
Console.WriteLine("{0}: car {1} is new", name, e.Car);
} bool IWeakEventListener.ReceiveWeakEvent(Type managerType, object sender, EventArgs e)
{
NewCarIsHere(sender, e as CarInfoEventArgs);
return true;
} }
}
主方法:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DelegateEvent
{
class Program
{
static void Main(string[] args)
{
//var dealer = new CarDealer();
//var michael = new Consumer("A"); //订阅者A
//dealer.NewCarInfo += michael.NewCarIsHere;
//dealer.NewCar("A_Car"); //A车到达 A得到通知 //var sebastian = new Consumer("B"); //订阅者B
//dealer.NewCarInfo += sebastian.NewCarIsHere;
//dealer.NewCar("B_Car"); //B车到达 A、B都得到通知 //dealer.NewCarInfo -= michael.NewCarIsHere; //A取消订阅
//dealer.NewCar("C_Car"); //C车到达 只有B得到通知 #region WeakEvent
var dealer = new CarDealer();
var michael = new WeakConsumer("A"); //订阅者A
WeakCarInfoEventManager.AddListener(dealer,michael);
dealer.NewCar("A_Car"); var sebastian = new WeakConsumer("B"); //订阅者B
WeakCarInfoEventManager.AddListener(dealer, sebastian);
dealer.NewCar("B_Car"); //B车到达 A、B都得到通知 WeakCarInfoEventManager.RemoveListener(dealer, michael);
dealer.NewCar("C_Car");
#endregion
}
}
}
CarDealer类 事件发布程序 不做任何更改
测试结果一致
事件发布程序和事件监听程序不再强连接
C#_事件委托的更多相关文章
- C#_事件
C#_事件 概述 今天用来演示事件的例子是模拟实现一个文件下载类,在这个类中我将定义一个DownLoad事件,这个事件用来在文件下载的过程中,向订阅这个事件的用户发出消息,而这个消息将用DownLoa ...
- Js 事件委托 解决动态元素不能click点击的问题
参考教程地址 https://blog.csdn.net/xiaolong20081/article/details/79792137 不想写了.直接看上面就行 采用事件委托或代理方式绑定 $(doc ...
- HTML 事件(三) 事件流与事件委托
本篇主要介绍HTML DOM中的事件流和事件委托. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三) 事件流与事件委托 4 ...
- js中的事件委托
原文 http://itindex.net/detail/48661-js-事件 1,什么是事件委托:通俗的讲,事件就是onclick,onmouseover,onmouseout,等就是事件,委托呢 ...
- js动态添加事件-事件委托
作者:白狼 出处:http://www.manks.top/javascript-dynamic-event.html 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给 ...
- js_事件委托
起因: 1.这是前端面试的经典题型,要去找工作的小伙伴看看还是有帮助的: 2.其实我一直都没弄明白,写这个一是为了备忘,二是给其他的知其然不知其所以然的小伙伴们以参考: 概述: 那什么叫事件委托呢?它 ...
- 怎么理解js中的事件委托
怎么理解js中的事件委托 时间 2015-01-15 00:59:59 SegmentFault 原文 http://segmentfault.com/blog/sunchengli/119000 ...
- jQuery-1.9.1源码分析系列(十) 事件系统——事件委托
jQuery的事件绑定有几个比较优秀的特点: 1. 可以绑定不限数量的处理函数 2. 事件可以委托到祖先节点,不必一定要绑到对应的节点,这样后添加的节点也照样能被处理. 3. 链式操作 下面主要分析事 ...
- js事件委托
什么是事件委托:通俗的讲,onclick,onmouseover,onmouseout,等就是事件,委托呢,就是让别人来做,这个事件本来是加在某些元素上的,然而你却加到别人身上来做,完成这个事件. 也 ...
随机推荐
- nodebb在阿里云主机部署过程
1.在centos上安装nodejswget http://nodejs.org/dist/v0.8.9/node-v0.8.9.tar.gztar zxvf node-v0.8.9.tar.gzcd ...
- Execl DataTime Format Number
Excel 中日期类型所保存的值是数值型.只是设置了为日期格式,通过公式转换从而得出我们平时常用的日期内容.也很好理解这公式所要说明的意思.数值是个浮点型可以分成2部分看.整数部分:年月日(日期)小数 ...
- MySQL 执行计划explain详解
MySQL 执行计划explain详解 2015-08-10 13:56:27 分类: MySQL explain命令是查看查询优化器如何决定执行查询的主要方法.这个功能有局限性,并不总会说出真相,但 ...
- cf B George and Cards
题意:给你一个只有‘.’和'#'的n*n的格子,问所有的'#'是不是只属于一个十字叉,如果不是输出NO,否则输出YES. #include <cstdio> #include <cs ...
- struts中的ignoreHierarchy 参数和root 参数
struts2 1.ignoreHierarchy 参数:表示是否忽略等级,也就是继承关系,比如:TestAction继承于BaseAction,那么TestAction中返回的json字符串默认是不 ...
- JS实现点击按钮,自增输入框个数
<html> <head> <script language="javascript"> var i=0; function addinput( ...
- poj2594
特殊的最小路径覆盖回顾一下经典的最小路径覆盖问题是每个点都恰好被一条路径覆盖我们把有向无环图的点拆成i,i',对于原图中边i--->j,连边i-->j'做最大匹配,答案是原图点数-最大匹配 ...
- BZOJ 1053 [HAOI2007]反素数ant
1053: [HAOI2007]反素数ant Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1948 Solved: 1094[Submit][St ...
- Apache CXF多个远程拒绝服务漏洞(CVE-2013-2160)
漏洞版本: Apache Group CXF <= 2.5.10 Apache Group CXF 2.7.4 Apache Group CXF 2.6.7 漏洞描述: BUGTRAQ ID: ...
- 矩阵(快速幂):COGS 963. [NOI2012] 随机数生成器
963. [NOI2012] 随机数生成器 ★★ 输入文件:randoma.in 输出文件:randoma.out 简单对比 时间限制:1 s 内存限制:128 MB [问题描述] 栋 ...