- 浏览: 675331 次
- 性别:
- 来自: 安徽
文章分类
- 全部博客 (252)
- Html/Div+CSS (12)
- Js/Jquery (34)
- Flex (2)
- Ajax (3)
- Java (35)
- C# (15)
- Spring (16)
- Hibernate (13)
- Struts2 (12)
- Struts1 (7)
- DWR (1)
- iBatis/myBatis (9)
- Tag(JSTL、EL) (1)
- Android (44)
- SQL (7)
- SEO (7)
- Exception (3)
- Tool (10)
- Other (3)
- WebService (9)
- Apache (7)
- Ext (0)
- Utils (12)
- thinking in programme (2)
- Hadoop (0)
- ActiveMQ (0)
- HTML5/CSS3 (0)
- WPF (1)
- NodeJs (1)
- 设计模式 (0)
- 程序人生 (1)
- 随笔 (1)
- Linux (1)
- Load Balance (0)
最新评论
-
drinkjava2:
太复杂了而且不通用,利用ThreadLocal可完美解决这一问 ...
JDBC的多条件动态查询 -
u013107014:
multipartRequest.getFiles(" ...
多文件上传 by MultipartFile and Multiple -
liyys:
可惜没讲你mysql数据库的表的设计
iBatis入门 -
Mapple_leave:
效果还是挺不错的,谢谢了。
中文简体与繁体的转换 -
arcpad:
JS禁用浏览器退格键
Delegate 是在.NET1.0 的时候就已经存在了的特性,因为在准备总结Lambda 表达式的时候发现自己对Delegate 还没有深刻的理解,所以打算先对Delegate 进行整理一下。
Delegate 中文译为“委托”,MSDN 中对Delegate 是这样进行解释的“C# 中的委托 类似于C 或C++ 中的函数指针。使用委托使程序员可以将方法引用封装在委托对象内 。然后可以将该委托对象传递给可调用所引用方法的代码,而不必在编译时知道将调用哪个方法。与C 或C++ 中的函数指针不同,委托是面向对象、类型安全的,并且是安全的 。”
我们来通过一个Demo 来进行理解:
class Program { static void OtherClassMethod() { Console .WriteLine("Delegate an other class's method" ); } static void Main(string [] args) { var test = new TestDelegate (); test.delegateMethod = new TestDelegate .DelegateMethod (test.NonStaticMethod); test.delegateMethod += new TestDelegate .DelegateMethod (TestDelegate .StaticMethod); test.delegateMethod += Program .OtherClassMethod; test.RunDelegateMethods(); Console .ReadKey(); } } class TestDelegate { // 声明了一个Delegate 类型名为DelegateMethod ,这种Delegate 类型可以搭载返回值为void ,无参函数 public delegate void DelegateMethod (); // 声明了一个Delegate 对象,注意一个是类型,一个是对象 public DelegateMethod delegateMethod; public static void StaticMethod() { Console .WriteLine("Delegate a static method" ); } public void NonStaticMethod() { Console .WriteLine("Delegate a non-static method" ); } public void RunDelegateMethods() { if (delegateMethod != null ) { Console .WriteLine("---------------------" ); delegateMethod.Invoke(); Console .WriteLine("---------------------" ); } } } |
通过:
test.delegateMethod = new TestDelegate .DelegateMethod (test.NonStaticMethod); test.delegateMethod += new TestDelegate .DelegateMethod (TestDelegate .StaticMethod); test.delegateMethod += Program .OtherClassMethod; |
我们可以发现 delegateMethod 搭载了3 个函数(通过+= 增加搭载的函数,也可以通过-= 来去掉Delegate 中的某个函数),而且通过delegateMethod.Invoke() 运行被搭载的函数,这就是Delegate 可以看作为函数指针的原因。而在Java 中没有委托机制,如果向要实现此功能个人感觉只有通过Java 的内部类来实现。
既然C# 中的委托与C++ 中函数指针如此相似,那么我简单整理一下Delegate 与函数指针的区别:
1、 一个delegate 对象一次可以搭载多个方法,而不是一次一个。当我们唤起一个搭载多个方法的delegate ,所有方法以开始被搭载到delegate 对象的顺序依次被唤起;
2、 一个delegate 对象所搭载的方法并不需要属于同一个类别,一个delegate 对象所搭载的所有方法必须具有与声明时相同的原型和形式,然而这些方法可以有static 也可以有non-static ,可以由一个或多个不同类别的成员组成;
3、 一个delegate type 的声明在本质上是创建了一个新的subtype instance ,该 subtype 派生自 .NET library framework 的 abstract base classes Delegate 或 MulticastDelegate ,它们提供一组public methods 用以询访delegate 对象或其搭载的方法(methods ) ,与函数指针不同,委托是面向对象、类型安全并且安全的。
Delegate 的使用场景:
首先先看下面这段代码
class Program { static void Main(string [] args) { var car = new Car (15); new Alerter (car); car.Run(120); Console .ReadKey(); } class Car { public delegate void Notify (int value); private int petrol = 0; public int Petrol { get { return petrol; } set { petrol = value ; if (petrol < 10) // 当petrol 的值小于10 时出发警报 { if (notifier != null ) { notifier.Invoke(Petrol); } } } } public Car(int petrol) { Petrol = petrol; } public void Run(int speed) { int distance = 0; while (Petrol > 0) { Thread .Sleep(500); Petrol--; distance += speed; Console .WriteLine("Car is running... Distance is " + distance.ToString()); } } } class Alerter { public Alerter(Car car) { car.notifier += new Car .Notify (NotEnoughPetrol); } public void NotEnoughPetrol(int value) { Console .ForegroundColor = ConsoleColor .Red; Console .WriteLine("You only have " + value.ToString() + " gallon petrol left!" ); Console .ResetColor(); } } } |
通过上面的代码,你可能会有这样的疑问,为什么不再public in Petrol 中直接调用Alerter.NotEnoughtPetrol 呢?因为Car 模块和Alerter 模块本身是两个独立的子系统,如果直接调用,则程序的耦合性就会增加,这是程序员的大忌。
其实上面的代码是设计模式中的观察者设计模式 的实现,当汽车在运行中汽油量<10 时,就会发出警报,在上面的代码中Delegate 相当于一个存放回调函数的函数指针,使用Delegate ,我们可以非常方便地实现观察者模式。而其实,在需要使用回调函数时,我们都可以考虑使用Delegate 。
下面我再举个例子吧,取生活中一个场景来说,孩子饿了,要哭,爸爸妈妈听到哭声都会赶过来。如果按照常规的编程方法,我们可能要在Child 类里边实现一个方法来通知爸爸和妈妈,假设有一天这家聚会,爷爷奶奶,姥姥姥爷,姑姑婶婶全过来了,那么孩子必须要通知增加的这些人,我们就不得不修改Child 类里的这个方法。而事实上我们可以这样考虑,将对孩子哭这一事件关心的一类人抽象出来,爷爷奶奶,姥姥姥爷,姑姑婶婶都从该类派生,他们有一个公共的代理,只要他们将自己的行为“注册”到这个代理,孩子一哭,所有被注册进去的事件就会形成一个事件的链表然后顺次执行。在这种模式下Child 类和Observer 类的派生类之间的耦合性大大降低了,我们不需要对Child 类的方法进行任何的修改而只需要讲Observer 类的派生类的各个实例对象对“孩子哭”这一事件的响应注册到“孩子哭”中就可以了。
class Program { public delegate void EventHandle (object sender, EventArgs e); class Entry { public static void Main() { Woman woman = new Woman (); Man man = new Man (); Child child = new Child (); child.call += new EventHandle (woman.observer_call); child.call += new EventHandle (man.observer_call); child.observer_call(null , null ); Console .ReadKey(); } } abstract class observer { public event EventHandle call; public void Subto(observer ob) { this .call += new EventHandle (ob.observer_call); } abstract public void observer_call(object sender, EventArgs e); public void Shout() { if (call != null ) { call(this , null ); } } } class Woman : observer { public override void observer_call(object sender, EventArgs e) { Console .WriteLine("Woman : Oh Baby, mom is coming!" ); Shout(); } } class Man : observer { public override void observer_call(object sender, EventArgs e) { Console .WriteLine("Man : Oh Baby, papa is coming!" ); Shout(); } } class Child : observer { public override void observer_call(object sender, EventArgs e) { Console .WriteLine("Child : Where are my parents? I'm hungry!" ); Shout(); } } } |
上面我定义了一个委托,它的作用是将被委托的函数以参数形式“传递”给事件,从而构成一个事件的链表。
说明,委托在编译的时候会编译成类,因为委托是一个类,所以在任何可以声明类的地方都可以声明委托。它定义了方法的类型,使得可以将方法当作另一个方法的参数传递,这种将方法动态的赋给参数的做法,可以避免在程序中大量地使用if else(switch) 语句,同时使得程序具有更好的扩展性;
在上面的“ public event Notify notifier; ”可以改写为“ public Notify notifier; ”这就是我下面需要整理的Delegate 与Event ;
Delegate 与Event :
通过项目发现很多时候Delegate 与Event 这两个关键字经常会在一起使用,那两者之间是什么关系呢?通过msdn 的解释是“声明事件:若要在类内声明事件,首先必须声明该事件的委托类型”
发表评论
-
C# 可选参数和命名参数
2013-09-05 22:39 1135不说废话,直接上代码 using Syste ... -
C#中JSON序列化和反序列化
2012-12-13 09:33 2691在做项目中使用EF时,发现DataContractJsonSe ... -
Android中http请求(C# MVC接收)
2012-11-28 08:54 4132Android 开发中很多涉及网络通信,因为项目中 ... -
Could not load file or assembly 'System.Data.SQLite' or one of its dependencies.
2012-08-10 09:43 149164位系统上发布net项目报: Could not load ... -
VS2008未能正确加载包visla Studio HTM Editor Package 问题的解决
2012-08-02 23:59 2037因为项目需要在原有 VS2010 的基础上又安装了 ... -
.Net MVC项目部署遇404问题
2012-07-26 00:47 2538MVC1 项目部署成功后,点击链接,会提示 ... -
DebuggerStepThrough 属性
2012-02-10 21:45 1420有时在使用F11进行调试时,经常会进入到一些不想进入的prop ... -
C#中部分类的使用(partial)
2012-02-11 22:18 2199今天工作中遇到了C# ... -
关于Repository模式
2012-02-06 21:49 5140Repository模式: 网上说Repository ... -
MVC2.0前置
2012-02-06 21:48 3619.NET MVC执行过程: 1、 ... -
public void Delete<T>(List<T> EntityList) where T : class, new()
2012-02-02 23:36 2768今天熟悉项目时遇到下面这段代码竟不知道什么意思,记录一下: ... -
C#3.0新特性
2011-12-29 18:37 1224C#3.0 的新特性主要有: ... -
方法参数关键字params、ref及out
2011-12-29 15:05 1138这是三个关键字通过字 ... -
Int?与Int??
2011-12-21 13:11 1322Int?与Int??: Int?:为泛型Nullable< ...
相关推荐
在C#编程中,委托和事件是两种非常重要的特性,它们是实现面向对象设计的关键工具,尤其是对于构建异步应用程序。下面将详细讲解这两个概念及其在异步编程中的应用。 一、委托 委托在C#中可以被视为一种类型,它...
在C#编程语言中,委托和事件是两个关键特性,它们...总的来说,理解和掌握C#的委托事件对于任何想要深入学习.NET框架的开发者来说都是至关重要的。通过实例学习,初学者和进阶者都能从中受益匪浅,提升自己的编程技能。
C#委托事件C#委托事件C#委托事件C#委托事件C#委托事件C#委托事件
计算机课程设计C#委托事件 通过分析给定的文件信息,我们可以生成以下知识点: 1. 什么是事件?事件是类在发生其关注的事情时用来提供通知的一种方式。事件的发生一般都牵扯2个角色:事件发行者(Publisher)和...
在C#编程中,委托、线程和事件是三个核心概念,它们对于构建高效、响应式的多任务应用程序至关重要。下面将详细阐述这三个概念及其相互之间的关系,并通过一个实例代码进行说明。 1. 委托(Delegate): 委托在C#中...
### C#中的委托和事件 #### 一、委托的基础概念 在C#中,委托是一种引用类型的数据结构,它允许将方法当作参数进行传递。简而言之,委托就是指向一个方法的引用。委托的主要用途是作为事件处理程序的类型。 **...
详解 C# 委托、事件与回调函数 委托是 C# 中一种非常重要的概念,它可以将方法作为参数传递给其他方法,也可以将方法作为返回值返回给其他方法。委托的定义是:delegate 返回类型 委托名(参数列表);例如:...
这是C# 委托与事件简单的使用例子。 只是为了初学者更好的接受委托与事件使用方法而已。 程序有两个窗体,一个是主窗体,一个是副窗体。 打开主窗体,在主窗体中点按钮后,打开副窗体,在副窗体中,可以调整主窗体...
在C#编程语言中,委托和事件是两个关键的概念,它们是实现面向对象设计模式,尤其是事件驱动编程的基础。本文将深入探讨这两个概念,并通过实例代码来帮助初学者理解和掌握。 **一、委托** 委托在C#中可以看作是...
基于c#程序对c语言中的委托事件进行详细的分析与讲解
在C#编程中,事件委托和订阅发布模式是核心特性之一,它们对于构建可扩展、模块化和松耦合的应用程序至关重要。事件是类之间通信的一种机制,它允许一个对象(发布者)通知其他对象(订阅者)某些特定操作的发生,而...
本文将深入讲解C#委托及其在实际编程中的应用。 首先,让我们了解什么是委托。在C#中,委托可以被看作是一种类型,这种类型能够引用具有相同签名的方法。签名包括方法的返回类型和参数列表。委托类是.NET框架提供的...
在C#编程语言中,委托和事件是两个非常重要的概念,它们构成了事件驱动编程的基础。本文将深入探讨这两个概念,以及它们在实际开发中的应用。 首先,我们来理解什么是委托。在C#中,委托是一种类型,它代表了方法的...
在C#编程语言中,委托和事件是两个关键的概念,它们是实现面向对象设计模式,尤其是事件驱动编程的核心。下面将详细阐述这两个概念及其在实际编程中的应用。 **委托** 委托在C#中相当于一种类型,它封装了指向方法...
委托(Delegate)和事件(Event)是C#中非常重要的两种机制,它们在.NET框架中扮演着极其重要的角色。理解这两种概念,对于深入学习C#编程语言,构建高效、可维护的程序架构至关重要。首先我们来探讨一下委托的概念...
例如,在串口接收事件中,可以使用委托(delegate)来更新控件内容: `SetText(ASCIIEncoding.ASCII.GetString(arr));` 在上面的代码中,`arr` 是 byte[] 类型的数据,用于传递给控件内容更新方法。 使用委托...