`
fkdexq
  • 浏览: 514 次
  • 性别: Icon_minigender_1
  • 来自: 广州
最近访客 更多访客>>
社区版块
存档分类
最新评论

C#教程:深入解析委托与事件的由来

阅读更多

本篇文章将为你介绍一下 Delegate 的使用方式,逐渐揭开 C# 当中事件(Event)的由来,它能使处理委托类型的过程变得更加简单。

  还将为您解释委托的协变与逆变,以及如何使用 Delegate 使 Observer(观察者)模式的使用变得更加简单。

  在事件的介绍上,会讲述事件的使用方式,并以asp.net的用户控件为例子,介绍一下自定义事件的使用。
  最后一节,将介绍Predicate、Action、Func多种泛型委托的使用和Lambda的发展过程与其使用方式。

  因为时间仓促,文中有错误的地方敬请点评。

  目录

  一、委托类型的来由

  二、建立委托类

  三、委托使用方式

  四、深入解析事件

  五、Lambda 表达式

  一、委托类型的来由

  记得在使用C语言的年代,整个项目中都充满着针指的身影,那时候流行使用函数指针来创建回调函数,使用回调可以把函数回调给程序中的另一个函数。但函数指针只是简单地把地址指向另一个函数,并不能传递其他额外信息。

  在.NET中,在大部分时间里都没有指针的身影,因为指针被封闭在内部函数当中。可是回调函数却依然存在,它是以委托的方式来完成的。委托可以被视为一个更高级的指针,它不仅仅能把地址指向另一个函数,而且还能传递参数,返回值等多个信息。系统还为委托对象自动生成了同步、异步的调用方式,开发人员使用 BeginInvoke、EndInvoke 方法就可以抛开 Thread 而直接使用多线程调用 。

  回到目录

  二、建立委托类

  使用delegate就可以直接建立任何名称的委托类型,当进行系统编译时,系统就会自动生成此类型。您可以使用delegate void MyDelegate() 方式建立一个委托类,并使用ILDASM.exe观察其成员。由ILDASM.exe 中可以看到,它继承了System.MulticastDelegate类,并自动生成BeginInvoke、EndInvoke、Invoke 等三个常用方法。

 

  Invoke 方法是用于同步调用委托对象的对应方法,而BeginInvoke、EndInvoke是用于以异步方式调用对应方法的。

  对于异步调用的使用方式,可以参考:C#综合揭秘——细说多线程

    1 public class MyDelegate:MulticastDelegate
    
  2 {
    
  3 //同步调用委托方法
    
  4 public virtual void Invoke();
    
  5 //异步调用委托方法
    
  6 public virtual IAsyncResult BeginInvoke(AsyncCallback callback,object state);
    
  7 public virtual void EndInvoke(IAsyncResult result);
    
  8 }

 


  MulticastDelegate是System.Delegate的子类,它是一个特殊类,编译器和其他工具可以从此类派生,但是自定义类不能显式地从此类进行派生。它支持多路广播委托,并拥有一个带有链接的委托列表,在调用多路广播委托时,系统将按照调用列表中的委托出现顺序来同步调用这些委托。

  MulticastDelegate具有两个常用属性:Method、Target。其中Method 用于获取委托所表示的方法Target 用于获取当前调用的类实例。

  MulticastDelegate有以下几个常用方法:

  方法名称 说明

  Clone 创建委托的浅表副本。

  GetInvocationList 按照调用顺序返回此多路广播委托的调用列表。

  GetMethodImpl 返回由当前的 MulticastDelegate 表示的静态方法。

  GetObjectData 用序列化该实例所需的所有数据填充 SerializationInfo 对象。

  MemberwiseClone 创建当前 Object 的浅表副本。

  RemoveImpl 调用列表中移除与指定委托相等的元素

  MulticastDelegate与Delegate给委托对象建立了强大的支持,下面向各位详细介绍一下委托的使用方式。

  三、委托使用方式

  3.1 简单的委托

  当建立委托对象时,委托的参数类型必须与委托方法相对应。只要向建立委托对象的构造函数中输入方法名称example.Method,委托就会直接绑定此方法。使用myDelegate.Invoke(string message),就能显式调用委托方法。但在实际的操作中,我们无须用到 Invoke 方法,而只要直接使用myDelegate(string message),就能调用委托方法。

 

 1 class Program
    
  2 {
    
  3 delegate void MyDelegate(string message);
    
  4
    
  5 public class Example
    
  6 {
    
  7 public void Method(string message)
    
  8 {
    
  9 MessageBox.Show(message);
    
  10 }
    
  11 }
    
  12
    
  13 static void Main(string[] args)
    
  14 {
    
  15 Example example=new Example();
    
  16 MyDelegate myDelegate=new MyDelegate(example.Method);
    
  17 myDelegate("Hello World");
    
  18 Console.ReadKey();
    
  19 }
    
  20 }

 

 

 

 

 

  3.2 带返回值的委托

  当建立委托对象时,委托的返回值必须与委托方法相对应。使用下面的例子,方法将返回 “Hello Leslie” 。

 1 class Program
    
  2 {
    
  3 delegate string MyDelegate(string message);
    
  4
    
  5 public class Example
    
  6 {
    
  7 public string Method(string name)
    
  8 {
    
  9 return "Hello " + name;
    
  10 }
    
  11 }
    
  12
    
  13 static void Main(string[] args)
    
  14 {
    
  15 Example example=new Example();
    
  16 //绑定委托方法
    
  17 MyDelegate myDelegate=new MyDelegate(example.Method);
    
  18 //调用委托,获取返回值
    
  19 string message = myDelegate("Leslie");
    
  20 Console.WriteLine(message);
    
  21 Console.ReadKey();
    
  22 }
    
  23 }

 

 

 

 

 

 

  3.3 多路广播委托

  在第二节前曾经提过,委托类继承于MulticastDelegate,这使委托对象支持多路广播,即委托对象可以绑定多个方法。当输入参数后,每个方法会按顺序进行迭代处理,并返回最后一个方法的计算结果。

  下面的例子中,Price 类中有两个计算方法,Ordinary 按普通的9.5折计算,Favourable 按优惠价 8.5 折计算。委托同时绑定了这两个方法,在输入参数100以后,Ordinary、Favourable这两个方法将按顺序迭代执行下去,最后返回 Favourable 方法的计算结果 85。

1 delegate double MyDelegate(double message);
    
  2
    
  3 public class Price
    
  4 {
    
  5 public double Ordinary(double price)
    
  6 {
    
  7 double price1 = 0.95 * price;
    
  8 Console.WriteLine("Ordinary Price : "+price1);
    
  9 return price1;
    
  10 }
    
  11
    
  12 public double Favourable(double price)
    
  13 {
    
  14 double price1 = 0.85 * price;
    
  15 Console.WriteLine("Favourable Price : " + price1);
    
  16 return price1;
    
  17 }
    
  18
    
  19 static void Main(string[] args)
    
  20 {
    
  21 Price price = new Price();
    
  22 //绑定Ordinary方法
    
  23 MyDelegate myDelegate = new MyDelegate(price.Ordinary);
    
  24 //绑定Favourable方法
    
  25 myDelegate += new MyDelegate(price.Favourable);
    
  26 //调用委托
    
  27 Console.WriteLine("Current Price : " + myDelegate(100));
    
  28 Console.ReadKey();
    
  29 }
    
  30 }

      1 2下一页

 


----本文来Net探索者,http://www.codefinds.net 转载请说明出处!

分享到:
评论

相关推荐

    net之美 : .net关键技术深入解析 (带目录高清版)

    本书是.NET 程序员进阶修炼的必读之作,由拥有多年开发经验的资深.NET 技术专家对C# 和.NET 中实用的、关键的和难以理解的知识点进行了深入解析,旨在帮助读者在尽可能短的时间内以 尽可能低的学习成本去掌握那些最...

    深入解析C#编程中泛型委托的使用

    主要介绍了C#编程中泛型委托的使用,引用泛型委托的代码可以指定类型参数以创建已关闭的构造类型,需要的朋友可以参考下

    .NET之美:.NET关键技术深入解析 - 张子阳

    .NET之美:.NET关键技术深入解析 - 张子阳 本书是.NET程序员进阶修炼的必读之作,由拥有多年开发经验的资深.NET技术专家对C#和.NET中实用的、关键的和难以理解的知识点进行了深入解析,旨在帮助读者在尽可能短的时间...

    .NET之美:.NET关键技术深入解析

    本书是.NET 程序员进阶修炼的必读之作,由拥有多年开发经验的资深.NET 技术专家对C# 和.NET 中实用的、关键的和难以理解的知识点进行了深入解析,旨在帮助读者在尽可能短的时间内以 尽可能低的学习成本去掌握那些最...

    C#5.0本质论第四版(因文件较大传的是百度网盘地址)

    C#5.0本质论第四版,高清扫描的,对C#5.0技术讲的比较详细,第1章 C#概述 1 1.1 Hello,World 1 1.2 C#语法基础 3 1.2.1 C#关键字 3 1.2.2 标识符 4 1.2.3 类型定义 5 1.2.4 Main 6 1.2.5...

    深入理解C#中常见的委托

    今天我要说的是C#中的三种委托方式:Func委托,Action委托,Predicate委托以及这三种委托的常见使用场景。Func,Action,Predicate全面解析首先来说明Func委托,通过MSDN我们可以了解到,Func委托有如下的5种类型: ...

    C#委托delegate实例解析

    主要介绍了C#委托delegate实例解析,对C#的委托做了较为深入的剖析,很适合初学者学习,需要的朋友可以参考下

    C#中的委托解析

    谈及到C#的基本特性,“委托”是不得不去了解和深入分析的一个特性。对于大多数刚入门的程序员谈到“委托”时,都会想到“将方法作为方法的参数进行传递”,很多时候都只是知道简单的定义,主要是因为“委托”在理解...

    CLR.via.C#.(中文第3版)(自制详细书签)

    《CLR via C#(第3版) 》针对.NET Framework 4.0和多核编程进行了全面更新和修订,是帮助读者深入探索和掌握公共语言运行时、C#和.NET开发的重要参考,同时也是帮助开发人员构建任何一种应用程序(如Microsoft ...

    CLR.via.C#.(中文第3版)(自制详细书签)Part2

    《CLR via C#(第3版) 》针对.NET Framework 4.0和多核编程进行了全面更新和修订,是帮助读者深入探索和掌握公共语言运行时、C#和.NET开发的重要参考,同时也是帮助开发人员构建任何一种应用程序(如Microsoft ...

    深入解析C#中的命名实参和可选实参

    这两种技术都可与方法、索引器、构造函数和委托一起使用。 在使用命名实参和可选实参时,将按实参出现在实参列表(而不是形参列表)中的顺序计算这些实参。 命名形参和可选形参一起使用时,您将能够只为可选形参列表...

    CLR.via.C#.(中文第3版)(自制详细书签)Part1

    《CLR via C#(第3版) 》针对.NET Framework 4.0和多核编程进行了全面更新和修订,是帮助读者深入探索和掌握公共语言运行时、C#和.NET开发的重要参考,同时也是帮助开发人员构建任何一种应用程序(如Microsoft ...

    CLR.via.C#.(中文第3版)(自制详细书签)Part3

    《CLR via C#(第3版) 》针对.NET Framework 4.0和多核编程进行了全面更新和修订,是帮助读者深入探索和掌握公共语言运行时、C#和.NET开发的重要参考,同时也是帮助开发人员构建任何一种应用程序(如Microsoft ...

    CSharp_delegate.rar_C#编程_C#_

    关于c# winform程序中委托的使用与深入解析。。

    .net之美 子阳

    本书是.NET 程序员进阶修炼的必读之作,由拥有多年开发经验的资深.NET 技术专家对C# 和.NET 中实用的、关键的和难以理解的知识点进行了深入解析,旨在帮助读者在尽可能短的时间内以 尽可能低的学习成本去掌握那些最...

    亮剑.NET深入体验与实战精要3

    4.5.3 委托与事件传递 179 4.6 实现个性化窗体界面 181 4.7 无标题窗体拖动的两种方法 183 4.8 让程序只启动一次——单实例运行 184 4.9 实现系统托盘和热键呼出 185 4.10 进程与多线程的区别 190 4.11 创建多线程...

    asp.net知识库

    理解C#中的委托[翻译] 利用委托机制处理.NET中的异常 与正则表达式相关的几个小工具 你真的了解.NET中的String吗? .NET中的方法及其调用(一) 如何判断ArrayList,Hashtable,SortedList 这类对象是否相等 帮助解决...

    LINQ 实战 1/11

    微软MVP呕心沥血之作,LINQ圣经,深入全面,引人入胜,丰富实例,兼顾C#和VB.NET语言。  本书作者是LINQ社区中的重要成员,他们在书中展示了这一技术的精髓……快去享受这一盛宴吧。  ——Matt Warren,微软主架构...

    亮剑.NET深入体验与实战精要2

    4.5.3 委托与事件传递 179 4.6 实现个性化窗体界面 181 4.7 无标题窗体拖动的两种方法 183 4.8 让程序只启动一次——单实例运行 184 4.9 实现系统托盘和热键呼出 185 4.10 进程与多线程的区别 190 4.11 创建多线程...

Global site tag (gtag.js) - Google Analytics