事件基于多播委托的特性。

  多播委托事实上就是一组类型安全的函数指针管理器,调用则执行顺序跳转到数组里所有的函数指针里执行。

    class Program
{
public class CarInfoEventArgs : EventArgs
{
public string Car { get; set; } public CarInfoEventArgs(string car)
{
this.Car = car;
}
} public class CarDealer
{
public event EventHandler<CarInfoEventArgs> NewCarInfo; //使用系统定义的泛型委托 public void NewCarcComing(string car)
{
Console.WriteLine("CarDealer, new car {0} has come.", car); EventHandler<CarInfoEventArgs> newCarInfo = NewCarInfo;
if (newCarInfo != null)
NewCarInfo(this, new CarInfoEventArgs(car));
}
} public 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);
}
} static void Main(string[] args)
{
var dealer = new CarDealer();
var personA = new Consumer("personA");
dealer.NewCarInfo += personA.NewCarIsHere;
dealer.NewCarcComing("Ferrari"); var personB = new Consumer("personB");
dealer.NewCarInfo += personB.NewCarIsHere;
dealer.NewCarcComing("BMW"); Console.ReadLine();
}
}

  

  基于该例,我们用“多播委托”的概念来重写:

    class Program
{
public class CarDealer
{
public Action<string> NewCarInfo; //使用系统定义的泛型委托 public void NewCarComing(string car)
{
Console.WriteLine("CarDealer, new car {0} has come.", car); if (NewCarInfo != null)
NewCarInfo(car);
}
} public class Consumer
{
private string name; public Consumer(string name)
{
this.name = name;
} public void NewCarIsHere(string car)
{
Console.WriteLine("{0}, car {1} is new", name, car);
}
} static void Main(string[] args)
{
var dealer = new CarDealer();
var personA = new Consumer("personA");
dealer.NewCarInfo += personA.NewCarIsHere;
dealer.NewCarComing("Ferrari"); var personB = new Consumer("personB");
dealer.NewCarInfo += personB.NewCarIsHere;
dealer.NewCarComing("BMW"); Console.ReadLine();
}
}

  我只想知道,在多播委托的基础上,事件有哪些自身的特性?从以上两个例子中似乎看不出来。

  继续来看下一个例子:

    class Program
{
public class CarDealer
{
public event Action<string> NewCarInfo; //使用系统定义的泛型委托 public void NewCarComing(string car)
{
Console.WriteLine("CarDealer, new car {0} has come.", car); if (NewCarInfo != null)
NewCarInfo(car);
}
} public class Consumer
{
private string name; public Consumer(string name)
{
this.name = name;
} public void NewCarIsHere(string car)
{
Console.WriteLine("{0}, car {1} is new", name, car);
}
} static void Main(string[] args)
{
var dealer = new CarDealer();
var personA = new Consumer("personA");
dealer.NewCarInfo += personA.NewCarIsHere;
dealer.NewCarInfo("Ferrari"); var personB = new Consumer("personB");
dealer.NewCarInfo += personB.NewCarIsHere;
dealer.NewCarInfo("BMW"); Console.ReadLine();
}
}

  1. 我们在委托之前加上“event”关键字;

  2. 我们在外部直接调用 委托实例;

  这个例子是编译不过的,由此可知 “event” 是不能直接由外部访问的。将该实例的 “event” 关键字拿掉,则可以编译通过。

 

    class Program
{
public class CarDealer
{
public event Action<string> NewCarInfo; //使用系统定义的泛型委托 public void NewCarComing(string car)
{
Console.WriteLine("CarDealer, new car {0} has come.", car); if (NewCarInfo != null)
NewCarInfo(car);
}
} public class Consumer
{
private string name; public Consumer(string name)
{
this.name = name;
} public void NewCarIsHere(string car)
{
Console.WriteLine("{0}, car {1} is new", name, car);
}
} static void Main(string[] args)
{
var dealer = new CarDealer();
var personA = new Consumer("personA");
dealer.NewCarInfo += personA.NewCarIsHere;
dealer.NewCarComing("Ferrari"); var personB = new Consumer("personB");
dealer.NewCarInfo += personB.NewCarIsHere;
dealer.NewCarComing("BMW"); Console.ReadLine();
}
}

  将         dealer.NewCarInfo("BMW");

改为了   dealer.NewCarComing("BMW");

  则可以编译通过,说明:委托实例是可以直接调用委托方法的,而事件则需要进一步封装,由此可知,事件是将委托方法私有化的封装

  再通过 反编译器 检查exe:

  可以看到,增加了 add_NewCarInfo, remove_NewCarInfo 两个方法,则进一步证明了我们对事件的定义:编译器生成了两个公有方法,来解决私有化委托后,外部无法为其增加或减少委托方法的问题

C# 基于委托的事件的更多相关文章

  1. .NET面试题系列[7] - 委托与事件

    委托和事件 委托在C#中具有无比重要的地位. C#中的委托可以说俯拾即是,从LINQ中的lambda表达式到(包括但不限于)winform,wpf中的各种事件都有着委托的身影.C#中如果没有了事件,那 ...

  2. .NET基础拾遗(4)委托、事件、反射与特性

    Index : (1)类型语法.内存管理和垃圾回收基础 (2)面向对象的实现和异常的处理基础 (3)字符串.集合与流 (4)委托.事件.反射与特性 (5)多线程开发基础 (6)ADO.NET与数据库开 ...

  3. [转载]C#委托和事件(Delegate、Event、EventHandler、EventArgs)

    原文链接:http://blog.csdn.net/zwj7612356/article/details/8272520 14.1.委托 当要把方法作为实参传送给其他方法的形参时,形参需要使用委托.委 ...

  4. C# 委托和事件(一):最简单的委托和事件

    C#的事件基于委托,所以先说委托. 一切脱离实际场景的抽象概念新手看上去就像是在扯犊子,不错,我就是个新手.所以我需要一个实际的场景. 明天刚好考试(商务英语),考试上有两个角色(class):老师( ...

  5. c#中委托和事件(续)(转)

    本文将讨论委托和事件一些更为细节的问题,包括一些大家常问到的问题,以及事件访问器.异常处理.超时处理和异步方法调用等内容. 为什么要使用事件而不是委托变量? 在 C#中的委托和事件 中,我提出了两个为 ...

  6. 第一章、C#委托和事件(Delegate、Event、EventHandler、EventArgs)

    第一章.C#委托和事件(Delegate.Event.EventHandler.EventArgs) 分类: 学习笔记-C#网络编程2012-12-08 14:10 7417人阅读 评论(3) 收藏  ...

  7. c#委托和事件(下) 分类: C# 2015-03-09 08:42 211人阅读 评论(0) 收藏

    C#中的委托和事件(下) 引言 如果你看过了 C#中的委托和事件 一文,我想你对委托和事件已经有了一个基本的认识.但那些远不是委托和事件的全部内容,还有很多的地方没有涉及.本文将讨论委托和事件一些更为 ...

  8. C#中委托和事件

    目 录 将方法作为方法的参数 将方法绑定到委托 更好的封装性 限制类型能力 范例说明 Observer 设计模式简介 实现范例的Observer 设计模式 .NET 框架中的委托与事件 为什么委托定义 ...

  9. C#委托和事件?策略模式?接口回调?还不清楚的赶紧来看我扯

    早前学习委托的时候,写过一点东西,今天带着新的思考和认知,再记点东西.这篇文章扯到设计模式中的策略模式,观察者模式,还有.NET的特性之一--委托.真的,请相信我,我只是在扯淡...... 场景练习 ...

随机推荐

  1. SRM 392(1-250pt)

    DIV1 250pt 题意:给两个各含有一个*号的字符串s1和s2,可以用一个任意字符串代替*号(注意是串,不是只能用单个字符代替,也可以为用空串代替),问能否将s1和s2变为相同的字符串.如果能输出 ...

  2. 简单的Goto运算演示程序

    /* * 该程序用于计算某个项集的Goto集 * RexfieldVon * 2013年8月11日2:34:50 */ #include <stdio.h> #include <st ...

  3. JSTL和select标签的组合使用

    1.用于根据不同的值显示对应的内容,不能选择 <select name="grade"> <c:choose> <c:when test=" ...

  4. 【转】WebStorm 2016 最新版激活(activation code方式)

    作者:=金刚=博客地址:http://www.cnblogs.com/woaic WebStorm 最新版本激活方式:今天下载最新版本的WebStorm,发现原来的通过license server激活 ...

  5. Unity三种截屏方法(非自带API)

    者利用了三种表现形式: 1,选择截图路径的方法 2,直接截取截屏的方法 3,截取鼠标圈选区域. 上代码,: 第一种是调用.net的类库,需要引用System.Windows.Forms.dll,在As ...

  6. Android Fragment动态添加 FragmentTransaction FragmentManager

    Fragment常用的三个类:android.app.Fragment 主要用于定义Fragmentandroid.app.FragmentManager 主要用于在Activity中操作Fragme ...

  7. leetcode第一刷_Construct Binary Tree from Preorder and Inorder Traversal

    构造方式跟中序与后序全然一样,并且一般都习惯正着来,所以更简单. 代码是之前写的,没实用库函数,不应该. TreeNode *buildIt(vector<int> &preord ...

  8. Android中自定义View的MeasureSpec使用

    有时,Android系统控件无法满足我们的需求,因此有必要自定义View.具体方法参见官方开发文档:http://developer.android.com/guide/topics/ui/custo ...

  9. Android(java)学习笔记227:服务(service)之服务的生命周期 与 两种启动服务的区别

    1.之前我们在Android(java)学习笔记171:Service生命周期 (2015-08-18 10:56)说明过,可以回头看看: 2.Service 的两种启动方法和区别: (1)Servi ...

  10. instancetype vs id for Objective-C

    instancetype: 使用 instancetype 编译器和IDE 会做类型检查,而id不会做完整的类型检查. A method with a related result type can ...