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. House of hello恶搞凯莉迷你包

    欧洲站 House of hello恶搞凯莉迷你包 最近淘宝卖的很疯,看看价格,俺咂舌不已 :1300-1600 今年迷你包卖的很疯我是知道的,迷你包今年没有买一个也是不行的! 剔除暴利,便宜的亲们不 ...

  2. Node.js事件发射器

    在Node很多对象发出事件,例如net.Server每个同级连接到它,一个fs.readStream发出打开文件事件时,每次都发出一个事件. 它发出事件的所有对象都是events.EventEmitt ...

  3. 【Java】Java XML 技术专题

    XML 基础教程 XML 和 Java 技术 Java XML文档模型 JAXP(Java API for XML Parsing) StAX(Streaming API for XML) XJ(XM ...

  4. 「Poetize9」升降梯口

    3056: 升降梯口 Time Limit: 2 Sec  Memory Limit: 128 MBSubmit: 43  Solved: 42[Submit][Status] Description ...

  5. C# 匿名方法 委托 Action委托 Delegate委托

    原文地址:https://msdn.microsoft.com/zh-cn/library/bb882516.aspx 匿名函数是一个“内联”语句或表达式,可在需要委托类型的任何地方使用. 可以使用匿 ...

  6. UVaLive5031 Graph and Queries(时光倒流+名次树)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=20332 [思路] 时光倒流+名次树(rank tree). 所谓“ ...

  7. SRM 405(1-250pt, 1-500pt)

    DIV1 250pt 题意:以linux系统中文件系统的路径表示方法为背景,告诉你某文件的绝对路径和当前位置,求相对路径.具体看样例. 解法:模拟题,不多说.每次碰到STL的题自己的代码都会显得很sb ...

  8. lightoj 1198 最大权重匹配

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1198 #include <cstdio> #include <cst ...

  9. loadView是干什么用的

    文/natewang(简书作者)原文链接:http://www.jianshu.com/p/f8d261d49615著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. viewContro ...

  10. 三星 note3销售地查询、销售地代码

    查看销售地代码 用KIES验销售地:记下设定-关于-状态里的序号. 手机不要连接电脑,注意是不要连接,打开KIES3,点工具——固件恢复和初始化,输入大写的型号SM-N900或者SM-N9005,确认 ...