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#_事件委托的更多相关文章

  1. C#_事件

    C#_事件 概述 今天用来演示事件的例子是模拟实现一个文件下载类,在这个类中我将定义一个DownLoad事件,这个事件用来在文件下载的过程中,向订阅这个事件的用户发出消息,而这个消息将用DownLoa ...

  2. Js 事件委托 解决动态元素不能click点击的问题

    参考教程地址 https://blog.csdn.net/xiaolong20081/article/details/79792137 不想写了.直接看上面就行 采用事件委托或代理方式绑定 $(doc ...

  3. HTML 事件(三) 事件流与事件委托

    本篇主要介绍HTML DOM中的事件流和事件委托. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三) 事件流与事件委托 4 ...

  4. js中的事件委托

    原文 http://itindex.net/detail/48661-js-事件 1,什么是事件委托:通俗的讲,事件就是onclick,onmouseover,onmouseout,等就是事件,委托呢 ...

  5. js动态添加事件-事件委托

    作者:白狼 出处:http://www.manks.top/javascript-dynamic-event.html 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给 ...

  6. js_事件委托

    起因: 1.这是前端面试的经典题型,要去找工作的小伙伴看看还是有帮助的: 2.其实我一直都没弄明白,写这个一是为了备忘,二是给其他的知其然不知其所以然的小伙伴们以参考: 概述: 那什么叫事件委托呢?它 ...

  7. 怎么理解js中的事件委托

    怎么理解js中的事件委托 时间 2015-01-15 00:59:59  SegmentFault 原文  http://segmentfault.com/blog/sunchengli/119000 ...

  8. jQuery-1.9.1源码分析系列(十) 事件系统——事件委托

    jQuery的事件绑定有几个比较优秀的特点: 1. 可以绑定不限数量的处理函数 2. 事件可以委托到祖先节点,不必一定要绑到对应的节点,这样后添加的节点也照样能被处理. 3. 链式操作 下面主要分析事 ...

  9. js事件委托

    什么是事件委托:通俗的讲,onclick,onmouseover,onmouseout,等就是事件,委托呢,就是让别人来做,这个事件本来是加在某些元素上的,然而你却加到别人身上来做,完成这个事件. 也 ...

随机推荐

  1. Redux1

    Redux 写在前面 写React也有段时间了,一直也是用Redux管理数据流,最近正好有时间分析下源码,一方面希望对Redux有一些理论上的认识:另一方面也学习下框架编程的思维方式. Redux如何 ...

  2. [转] Java 8的新特性

    简介 毫无疑问,Java 8是Java自Java 5(发布于2004年)之后的最重要的版本.这个版本包含语言.编译器.库.工具和JVM等方面的十多个新特性.在本文中我们将学习这些新特性,并用实际的例子 ...

  3. api1

    http://www.android-doc.com/reference/android/app/Fragment.html

  4. BZOJ 1055 玩具取名

    Description 某人有一套玩具,并想法给玩具命名.首先他选择WING四个字母中的任意一个字母作为玩具的基本名字.然后他会根据自己的喜好,将名字中任意一个字母用“WING”中任意两个字母代替,使 ...

  5. X-Plosives

    uvaLive 3644:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&pa ...

  6. hdu 5144 NPY and shot

    http://acm.hdu.edu.cn/showproblem.php?pid=5144 题意:给你初始的高度和速度,然后让你求出水平的最远距离. 思路:三分枚举角度,然后根据公式求出水平距离. ...

  7. ibatis动态语句加and 和不加and

    <select id="queryGoodsGroupCodeName" parameterClass="String" resultClass=&quo ...

  8. BAT互联网公司是如何内部推荐的?

    中国十大互联网公司 注:以上按照目前市值排序整理出来,当然还有更多未上市的潜力股.如:美团.豆瓣.豌豆荚.美图秀秀等等 各大互联网公司招聘官网 阿里招聘:https://job.alibaba.com ...

  9. setjmp/longjmp 使用

    C语言中有一个goto语句,其可以结合标号实现函数内部的任意跳转(通常情况下,很多人都建议不要使用goto语句,因为采用goto语句后,代码维护工作量加大).另外,C语言标准中还提供一种非局部跳转“n ...

  10. FSB\QPI\DMI总线的区别

    FSB\QPI\DMI总线的区别 zjdyx91                     一些客户问:intel CPU有的是前端总线(FSB),有的是QPI总线,有的又是DMI总线,这就把人弄晕了, ...