由于C#托管代码中是没有指针的,所以当要把一个函数做为一个参数传给另外一个函数时,用正常方法就没办法了,由于就弄出了个代理(Delegate),当然C#中的代理也只是类似函数指针,它除了能实现函数指针的功能外还有其他一些特性.
先来说下C++中的函数指针:
void PrintNum(int num) { cout<<num;} //一个打印数字的简单函数
void (*FunPtr)(int); //声明一个函数指针
FunPtr = PrintNum; //函数指针指向函数PrintNum
//下面几个语句都是等价的
PrintNum(8);
(*PrintNum)(8);
FunPtr(8);
(*FunPtr)(8);
void Fun(int num,void (*FunPtr)(int)) { FunPtr(num);} //函数指针做为参数传给另外一个函数
Fun(8,FunPtr); //调用上面的函数
C# 代理(Delegate)
说完了指针就来说与它类似的Delegate:
void PrintNum(int num) { Console.Write(num);} //一个打印数字的简单函数
delegate void DePrintNum(int num); //声明一个代理,有点类似声明一个指针,在C#中的话有点类似自定义的一个类型
DePrintNum de; //定义一个定理变量
de= PrintNum; //实例化变量de,相当于指针变量指向一个函数,它和语句de = new DePrintNum(PrintNum);是等价的
de(8); //打印数字8,和PrintNum(8)结果相同
void PrintSomething(int num,DePrintNum de) { de(num);} //把代理变量当参数传递,相当于把函数当参数传递
PrintSomething(8,de); //调用上面的函数
上面是代理和函数指针类似的地方,但它还是些另外的特性,比如可以把多个函数绑定到一个代理变量上
假如还有函数void PrintEno(int num) { Console.Write(num + 1);}
de += PrintEno; //de -= PrintNum就是去掉和函数PrintNum的绑定
de(8); //此时相当于同时调用了PrintNum(8)和PrintEno(8);
C# 事件(Event)
我们都知道C#很喜欢按照面向对象的思想来,本来类中随便声明个变量(标准叫法是字段),但还要再弄个属性出来把它再封装下.
那有个代理之后自然也想个法子把它封装下,于是就有个事件(Event):
比如上面有声明了代理
delegate void DePrintNum(int num);
public event DePrintNumePrintNum ; //其实和声明一个代理变量类似DePrintNum de;相当于把de封装了.不过这里没有用到de,类似于直接用属性没有了字段
ePrintNum += PrintNum; //事件里只能用+=,-=了,不能直接来个等号绑定函数了啊.这里自然也可以用+=连续绑定多个函数
ePrintNum(8); //调用事件,这跟代理一样,都相当于是一个函数指针,去间接的调用函数
//补充:事件和代理用起来区别不太大,只是声明的时候不太一样,不过另外还有个比较大的区别:假如ePrintNum是在类Class1中声明的,则像ePrintNum(8)这样的调用只能
在Class1中才是对的,如果在其他类中都不能实例化一个Class1再调用,只能通过+=,-=去给事件绑定或去掉函数,而如果代理的话就可以通过实例化Class1,然后直接调用代理.这或许就是封装性的一个好处了吧.假如不想让另外的类调用你的代理,而只想让它绑定个函数过来,就可以把代理封装成事件了.
补充
在C#中可能碰到事件最多的地方是.net里面自动生成的很多事件,比如点击下鼠标之类的都对就一个事件,不过我们写代码时只要写事件最终绑定的那个函数里的代码就行了.其他的就不用管了.
另外我们知道C#里面没有了全局函数,全局变量,所有的东西都整到了一个个的class中(或者struct中),但是其实我们发现枚举(enum),代理的声明除了放在class中外也可以放在 class外.其实我们把enum看成类似struct,把代理看成类似class就比较好理解了.
分享到:
相关推荐
c#的回调函数(delegate关键字)
关于Delegate【代理、委托】是C#中一个非常重要的概念,向前可以推演到C++的指针,向后可以延续到匿名方法、lambda表达式。 现在我就从一个最简单最实用的一个小例子出发分析一下Delegate的使用。 现在有两个窗体...
C# Delegate讲解C# Delegate讲解C# Delegate讲解C# Delegate讲解
C#中的事件和委托(Delegate,Event)
Delegate.Event.ThreadDelegate.EvDelegate.Event.Threadent.Thread
与指向成员函数的 C 指针不同,委托同时封装对象实例和方法。委托声明定义从类 System.Delegate 派生的类。委托实例封装一个或多个方法,每个方法都被称为可调用实体。对于实例方法,可调用实体由一个实例和该实例上...
c#中关于委托delegate的经典的实例,可以使我们清楚的了解delegate的使用方法及含义。
适合初学者了解C#的delegate,是一个非常简单的例子。
委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易。它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见到委托和事件就...
C# delegate thread范例 若不懂在代码中,线程如何调用的可以看看
C#中的委托类似于C或C++中的函数指针。使用委托使程序员可以将方法引用封装在委托对象内。然后可以将该委托对象传递给可调用所引用方法的代码,而不必在编译时知道将调用哪个方法。与C或C++中的函数指针不同,委托...
网上有很多关于C++ delegate机制的文章,但都讲的是函数指针的内容,上周就C++中实现C#的delegate机制的问题研究了好几天,查看了很多相关资料,才解决了问题,现将我写的C++ delegate测试程序贴出来,希望能帮到有...
最近收集的VB.Net-C#多线程Thread-代理委托delegate编程。文章列表: c#.net多线程同步.txt C#WebBrowser页面与WinForm交互技巧一.txt C#多线程编程-多细全.txt C#多线程编程简单实例.txt C#多线程窗体控件安全访问....
delegate本质上就是一个指向函数的指针,可以指向不同的函数,只要函数的签名和代理一致即可。 2 delegate应用 其实Func, Action, Predicate等都是delegate,只是特殊的delegate而已。delegate的巧妙应用,可以...
CSharp_Delegate C#委托 本人博客中的示例代码
我自己写的一个博文配的例子,博文地址待审核后加上去。
本文实例讲述了C#事件处理和委托event delegate,分享给大家供大家参考。具体方法如下: 以下仅仅是用最简单的方式表示事件,实际应用可能是不同窗体之间相互通知某些操作,达到触发。 首先声明一个degate的 ...
delegate与事件的实例,很简单的例子,帮助初学者理解,其中有两个delegate,一个有参数,一个无参数
C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托(Delegate) 是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。 委托(Delegate)特别用于实现事件和回调方法。所有的委托(Delegate...