来源:http://www.csharpwin.com/csharpspace/12119r2216.shtml

委托的声明

public delegate void MyDelegate(string str);

1.委托的定义和方法的定义类似,只是在前面加了一个delegate,但委托不是方法,它是一种类型。是一种特殊的类型,看成是一种新的对象类型比较好理解。用于对与该委托有相同签名的方法调用。
2.委托相当于C++中的函数指针,但它是类型安全的。
3.委托是从System.Delegate派生,但不能象定义常规类型一样直接从System.Delegate派生,对委托的声明只能通过上面的声明格式进行定义。关键字delegate通知编译器这是一个委托类型,从而在编译的时候对该类进行封装,对这一过程C#定义了专门的语法来处理这一过程。
4.不能从一个委托类型进行派生,因为它也是默认sealed的
5.委托即可以对静态方法进行调用也可以对实例方法进行调用。
6.每个委托类型包含一个自己的调用列表,当组合一个委托或从一个委托中删除一个委托时都将产生个新的调用列表。
7.两个不同类型的委托即使它们有相同的签名和返回值,但还是两个不同类型的委托。但其实在使用中可看作是相同的。

委托的比较

C#中对委托定义了两个操作符 == 和 !=
在以下情况下两个委托是相等的:
1.当两个委托都同时为null的时候
2.当两个委托都不为null时,下列情况下是相等的。
a.当两个委托的各自的调用列表只含有一个入口点的时候
   在下列情况下是相等的
   (1) 调用同一对象的同一静态方法
   (2) 调用同一对象的同一实例方法
b.当两个委托具有多个入口点时
   在下列情况下是相等的
   (1)只有当它们调用列表中的调用的方法按顺序都一一对应相同的对象及对象的同一方法的时候如上所述的两个不同类型的委托但是它们具有相同的签名和返回值时,只要满足上述条件的,即使它们类型不同,但比较的结果也是相同的。

委托的异常处理

当调用该委托的方法中发生了异常时,首先在调用该委托的方法中搜寻catch语句块。如果没有,则去该委托调用的方法中去寻找有没有catch语句块,这和调用方法发生异常的处理是一样的。当调用一个为null的委托即委托中列表中不存在调用方法时,将发生NullRefrenceException

委托的注意点:
当一个委托有多个入口点的时候,调用委托将依该委托的调用列表中的方法的顺序依次调用.这些方法共享一个参数集合,所以当委托有返回值的时候调用完这个委托后的返回值是最后一个方法的返回值或是有out参数.如果该委托的参数为ref(引用类型),那么在招待第一个方法的时候如果对这个参数的值有所改变,那么这个改变将会影响到后面的方法调用.

委托的一个例子

using System;
using System.Collections.Generic;
using System.Text;namespace ConsoleApplication1
{class Program{static void Main(string[] args){// 创建一个委托实例,封装C类的静态方法M1MyDelegate d1 = new MyDelegate(C.M1);d1("D1"); // M1// 创建一个委托实例,封装C类的静态方法M2MyDelegate d2 = new MyDelegate(C.M2);d2("D2"); // M2// 创建一个委托实例,封装C类的实例方法M3MyDelegate d3 = new MyDelegate(new C().M3);d3("D3"); // M3// 从一个委托d3创建一个委托实例MyDelegate d4 = new MyDelegate(d3);d4("D4"); // M3// 组合两个委托MyDelegate d5 = d1 + d2;d5 += d3;d5("D5"); // M1,M2,M3// 从组合委托中删除d3MyDelegate d6 = d5 - d3;d6("D6"); // M1,M2d6 -= d3; // 虽然d6调用列表中已经没有d3了,但这样只是不可能的移除没有错误发生d6("D6"); // M1,M2d6 -= d6;//d6("D6"); 此时d6的调用列表为空,d6为null,所以引发System.NullReferenceException
MyDelegate d7 = new MyDelegate(C1.P1);d7("D7"); // C1.P1
MyDelegate d8 = new MyDelegate(new C2().P1);d8("D8"); // C2.P1
}}// 声明一个委托MyDelegatepublic delegate void MyDelegate(string str);public class C{public static void M1(string str){Console.WriteLine("From:C.M1:   {0}", str);}public static void M2(string str){Console.WriteLine("From:C.M2:   {0}", str);}public void M3(string str){Console.WriteLine("From:C.M3:   {0}", str);}}public class C1{public static void P1(string str){Console.WriteLine("From:C1.P1:   {0}", str);}}public class C2{public void P1(string str){Console.WriteLine("From:C2.P1:   {0}", str);}}
}

事件委托

事件概述

事件就是当对象或类状态发生改变时,对象或类发出的信息或通知。发出信息的对象或类称为"事件源",对事件进行处理的方法称为"接收者",通常事件源在发出状态改变信息时,它并不知道由哪个事件接收者来处理.这就需要一种管理机制来协调事件源和接收者,C++中通过函数指针来完成的.在C#中事件使用委托来为触发时将调用的方法提供类型安全的封装

事件的声明

1.声明一个委托
public delegate void EventHandler(object sender, System.EventArgs e);

2.声明一个事件
public event EventHandler Changed;

3.引发一个事件
public OnChanged(EnventArgs e)
{
 if ( Changed != null)
 {
  Changed(this,e);
 }
}

4.定义事件处理程序
public MyText_OnChanged(Object sender,EventArgs e)
{
 ...
}

5.订阅事件(将事件处理程序添加到事件的调用列表中)

myText.Changed += EventHandler(MyText_OnChanged);

下面的一个小例子说明了怎样定义一个完整的事件机制:

using System;
using System.Collections.Generic;
using System.Text;namespace ConsoleApplication1
{class Program{        static void Main(string[] args){              MyText myText = new MyText();// 将事件处理程序添加到事件的调用列表中(即事件布线)myText.Changed += new MyText.ChangedEventHandler(myText_Changed);         string str = "";while (str != "quit"){Console.WriteLine("please enter a string:");str = Console.ReadLine();myText.Text = str;}}// 对Change事件处理的程序private static void myText_Changed(object sender, EventArgs e){Console.WriteLine("text has been changed  :{0}\n" ,((MyText)sender).Text);}        }  public class MyText{private string _text = "";// 定义事件的委托public delegate void ChangedEventHandler(object sender, EventArgs e);// 定义一个事件public event ChangedEventHandler Changed;// 用以触发Change事件protected virtual void OnChanged(EventArgs e){if (this.Changed != null)this.Changed(this, e);}// Text属性public string Text{get { return this._text; }set{this._text = value;// 文本改变时触发Change事件this.OnChanged(new EventArgs());}}}
}   

转载于:https://www.cnblogs.com/whpepsi/archive/2013/01/28/2879495.html

C#委托与事件 简明相关推荐

  1. 对张子阳先生对委托和事件的两篇文章的读后思考(说得很透,内附故事一篇)...

    第一篇 C#中的委托和事件 第二篇 C#中的委托和事件(续) 首先,张子阳先生的这是两篇关于委托和事件间关系的文章,是目前为止我读过的介绍委托和事件以及异步调用最简明清晰文章,作者通过非常有节奏的&q ...

  2. [C#]委托和事件(讲解的非常不错)

    引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去 ...

  3. .NET基础示例系列之六:委托及事件

    委托是一个类. 定义委托时,实是定义一个用户自定义的类,它能代表具有相同参数列表和返回类型的任何方法,方法可以是静态方法或成员方法.示例: public partial class Form1 : F ...

  4. 大白话系列之C#委托与事件讲解(一)

    从序言中,大家应该对委托和事件的重要性有点了解了吧,虽然说我们现在还是能模糊,但是从我的大白话系列中,我会把这些概念说的通俗易懂的.首先,我们还是先说说委托吧,从字面上理解,只要是中国人应该都知道这个 ...

  5. 委托、事件、事件访问器

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace 委托与事 ...

  6. js中的事件委托或是事件代理详解(转载)

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

  7. JS事件委托或者事件代理原理以及实现

    事件委托(事件代理)原理:简单的说就是将事件交由别人来执行,就是将子元素的事件通过冒泡的形式交由父元素来执行. 为什么要用时间委托? 在JavaScript中,添加到页面上的事件处理程序数量将直接关系 ...

  8. 对C#下函数,委托,事件的一点理解!

    <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> 今天一来是有点 ...

  9. 13委托和事件在观察者模式中的应用

    当一个被监视对象的方法执行会触发观察者Observer的方法的时候,我们就可以在被监视对象中声明委托和事件. 例子 有一个宠物追踪器挂宠物身上,只要宠物离开主人100米之外,主人手上的显示器显示警告信 ...

最新文章

  1. zookeeper适用场景:zookeeper解决了哪些问题
  2. xampp配置xdebug
  3. 【十五分钟Talkshow】谈谈HTML 5及其对Web开发人员的挑战和机遇
  4. 如何简化临时内存的分配与释放
  5. 读《程序是怎样跑起来》第五章有感
  6. springboot 不同环境不同的配置
  7. C++学习笔记:(一)面向对象 类与对象
  8. java多进程、多线程讲解
  9. SpringCloud微服务:Ribbon和Feign组件,实现服务调用的负载均衡
  10. C语言课后习题(29)
  11. python之路 day5
  12. api下载文件三种方式
  13. Caused by: java.lang.SecurityException: com.example.geofences from uid 10049 not allowed to perform
  14. smartsvn基本操作
  15. 净览杏蚜诰接煤檀郊炎
  16. Excel 高级筛选实现多条件筛选数据
  17. macOS Big Sur 11.7 (20G817) Boot ISO 原版可引导镜像
  18. 苹果8屏幕测试软件,iPhone8人脸识别软件
  19. DIH-全量导入总结
  20. 第三方INF不包含数字签名信息

热门文章

  1. ATLAS入门篇之HoverMenuExtender控件编程(2)
  2. c++局部对象是什么_面向对象三大特征: 封装
  3. 增加自增列 耗时长_又一批长事务,P0故障谁来背锅?
  4. 4.3.2 IP数据报分片
  5. ADC的有效位数和信纳比计算
  6. linux 编译器错误,linux – GHCi – Haskell编译器错误 – /home/user/.ghci归其他人所有,IGNORING...
  7. potplayer设置前进后退时间
  8. String和int 转换
  9. 《软件建模与设计: UML、用例、模式和软件体系结构》一一2.10 UML扩展机制
  10. Embedding Lua, in Scala, using Java(转)