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. Python学习 - 使用BeautifulSoup来解析网页一:基础入门

    写技术博客主要就是总结和交流的,如果文章用错,请指正啊! 以前一直在使用SGMLParser,这个太费时间和精力了,现在为了毕业设计,改用BeautifulSoup来实现HTML页面的解析工作的. 一 ...

  2. Mvc controller单元测试 Mock Url对象

    被测试Action 包含有Url对象的代码: data = new data { title = ds.Name, icon = "folder", attr = new { id ...

  3. 优化MYSQL FILESORT

    用Explain分析SQL语句的时候,经常发现有的语句在Extra列会出现Using filesort,根据mysql官方文档对他的描述: 引用 MySQL must do an extra pass ...

  4. java 和javaw 的区别——<转>

    java 和javaw 的区别 javaw.exe用法和java.exe 相同 javaw的程序不在java console 上面显示任何东西,如果在开发程序,就用java,这样可以看到错误提示, 如 ...

  5. 关于form.item不兼容的问题

    form.item()能在IE下运行,在firefox中会报脚本错误,没有这个函数. 可以使用 Form.elements 方法得到 HTMLCollection 后再使用 item 方法获取表单内元 ...

  6. 【HDOJ】3459 Rubik 2×2×2

    模拟+DFS. /* 3459 */ #include <cstdio> #include <cstring> #include <cstdlib> #define ...

  7. 数据结构(主席树):HDU 5654 xiaoxin and his watermelon candy

    Problem Description During his six grade summer vacation, xiaoxin got lots of watermelon candies fro ...

  8. 【动态规划】【最长公共子序列】Vijos P1111 小胖的水果

    题目链接: https://vijos.org/p/1111 题目大意: 多组数据,给两个字符串s1,s2,求把s1,s2拆开从前往后合并后最短是多少 apple + peach = appleach ...

  9. Count Primes ——LeetCode

    Description: Count the number of prime numbers less than a non-negative number, n. 题目大意:给一个int,返回小于它 ...

  10. FreeMarker-TemplateLoader

    Java中不乏优秀的模板引擎,Velocity,mvel,FreeMarker等.在构建框架的时候,通常可以拿来即用,但我们需要控制它.最近需要一个数据准备的框架,便选择了FreeMarker,Fre ...