使用C#委托的好处是什么

double祺永远被保佑 2012-10-15 07:34:01
我是初学者,亲问一下大家知道C#中使用委托的好处是什么?委托常用吗?直接调用函数就行了,为什么还要用一个“函数指针”来调用函数,实在想不明白????
...全文
3791 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
zmidl 2013-08-26
  • 打赏
  • 举报
回复
引用 2 楼 gefangliang 的回复:
C# 代理实际上类似于C++中的函数指针,因为C#中不存在指针,所以用代理可以完成一些原来在C++中用函数指针完成的操作,例如传递一个类A的方法m给另一个类B的对象,使得类B的对象能够调用这个方法m。但与函数指针相比,delegate有许多函数指针不具备的优点。首先,函数指针只能指向静态函数,而delegate既可以引用静态函数,又可以引用非静态成员函数。在引用非静态成员函数时,delegate不但保存了对此函数入口指针的引用,而且还保存了调用此函数的类实例的引用。其次,与函数指针相比,delegate是面向对象、类型安全、可靠的受控(managed)对象。也就是说,runtime能够保证delegate指向一个有效的方法,你无须担心delegate会指向无效地址或者越界地址。 实现一个delegate是很简单的,通过以下3个步骤即可实现一个delegate: 1.声明一个delegate对象,它应当与你想要传递的方法具有相同的参数和返回值类型。 声明一个代理的例子: public delegate int MyDelegate(string message); 2.创建delegate对象,并将你想要传递的函数作为参数传入。 创建代理对象的方法: 1). MyDelegate myDelegate = new MyDelegate(实例名.方法名); 2). MyDelegate myDelegate = new MyDelegate(类名.方法名); 注:如果需要代理的方法是一个static静态方法的话,采用第2种方式,否则采用第1种方式。 3.在要实现异步调用的地方,通过上一步创建的对象来调用方法。 可以直接使用代理调用代理所指向的方法: myDelegate(向方法传递的参数); 下面是一些需要注意的事情: “代理”(delegate)(代表、委托):“代理”是类型安全的并且完全面向对象的。 (1)在C#中,所有的代理都是从System.Delegate类派生的(delegate是System.Delegate的别名)。 (2)代理隐含具有sealed属性,即不能用来派生新的类型。 (3)代理最大的作用就是为类的事件绑定事件处理程序。 (4)在通过代理调用函数前,必须先检查代理是否为空(null),若非空,才能调用函数。(5)在代理实例中可以封装静态的方法也可以封装实例方法。 (6)在创建代理实例时,需要传递将要映射的方法或其他代理实例以指明代理将要封装的函数原型(.NET中称为方法签名:signature)。注意,如果映射的是静态方法,传递的参数应该是类名.方法名,如果映射的是实例方法,传递的参数应该是实例名.方法名。 (7)只有当两个代理实例所映射的方法以及该方法所属的对象都相同时,才认为它们是想等的(从函数地址考虑)。 (8)多个代理实例可以形成一个代理链,System.Delegate中定义了用来维护代理链的静态方法Combion,Remove,分别向代理链中添加代理实例和删除代理实例。 (9)代理三步曲: a.生成自定义代理类:delegate int MyDelegate(); b.然后实例化代理类:MyDelegate d = new MyDelegate(MyClass.MyMethod); c.最后通过实例对象调用方法:int ret = d();
只要用C++的指针来理解委托的 都是门外汉
yinhaichao2012 2013-08-05
  • 打赏
  • 举报
回复
引用 1 楼 findcaiyzh 的回复:
回调 -- 实际就是作为函数参数。 实现观察者模式 解耦-- Form1打开Form2,Form2变化通知Form1.函数调用的话Form2需要知道Form1.委托则不需要知道。
是委托模式吧?观察者模式不是发布者和订阅者么?
devmiao 2012-11-30
  • 打赏
  • 举报
回复 2
要明白直接调用和委托调用的区别。 委托可以将一个函数代表为一个变量在程序中传递。 委托可以实现回调,也就是被调用者反过来调用由调用者定义的函数,这个普通调用是做不到的。 调用者能反过来调用由调用者定义的函数,可以实现程序的双向通讯,被调用者也可以通知调用者,这是其一,其二,你可以创建一个算法或者操作的框架,并且某些具体操作由调用者定义,提高了程序的通用性。
心灵彩虹 2012-10-15
  • 打赏
  • 举报
回复
C# 代理实际上类似于C++中的函数指针,因为C#中不存在指针,所以用代理可以完成一些原来在C++中用函数指针完成的操作,例如传递一个类A的方法m给另一个类B的对象,使得类B的对象能够调用这个方法m。但与函数指针相比,delegate有许多函数指针不具备的优点。首先,函数指针只能指向静态函数,而delegate既可以引用静态函数,又可以引用非静态成员函数。在引用非静态成员函数时,delegate不但保存了对此函数入口指针的引用,而且还保存了调用此函数的类实例的引用。其次,与函数指针相比,delegate是面向对象、类型安全、可靠的受控(managed)对象。也就是说,runtime能够保证delegate指向一个有效的方法,你无须担心delegate会指向无效地址或者越界地址。

实现一个delegate是很简单的,通过以下3个步骤即可实现一个delegate:
1.声明一个delegate对象,它应当与你想要传递的方法具有相同的参数和返回值类型。
声明一个代理的例子:
public delegate int MyDelegate(string message);

2.创建delegate对象,并将你想要传递的函数作为参数传入。
创建代理对象的方法:
1). MyDelegate myDelegate = new MyDelegate(实例名.方法名);
2). MyDelegate myDelegate = new MyDelegate(类名.方法名);
注:如果需要代理的方法是一个static静态方法的话,采用第2种方式,否则采用第1种方式。

3.在要实现异步调用的地方,通过上一步创建的对象来调用方法。
可以直接使用代理调用代理所指向的方法:
myDelegate(向方法传递的参数);

下面是一些需要注意的事情:
“代理”(delegate)(代表、委托):“代理”是类型安全的并且完全面向对象的。
(1)在C#中,所有的代理都是从System.Delegate类派生的(delegate是System.Delegate的别名)。
(2)代理隐含具有sealed属性,即不能用来派生新的类型。
(3)代理最大的作用就是为类的事件绑定事件处理程序。
(4)在通过代理调用函数前,必须先检查代理是否为空(null),若非空,才能调用函数。(5)在代理实例中可以封装静态的方法也可以封装实例方法。
(6)在创建代理实例时,需要传递将要映射的方法或其他代理实例以指明代理将要封装的函数原型(.NET中称为方法签名:signature)。注意,如果映射的是静态方法,传递的参数应该是类名.方法名,如果映射的是实例方法,传递的参数应该是实例名.方法名。
(7)只有当两个代理实例所映射的方法以及该方法所属的对象都相同时,才认为它们是想等的(从函数地址考虑)。
(8)多个代理实例可以形成一个代理链,System.Delegate中定义了用来维护代理链的静态方法Combion,Remove,分别向代理链中添加代理实例和删除代理实例。
(9)代理三步曲:
a.生成自定义代理类:delegate int MyDelegate();
b.然后实例化代理类:MyDelegate d = new MyDelegate(MyClass.MyMethod);
c.最后通过实例对象调用方法:int ret = d();
宝_爸 2012-10-15
  • 打赏
  • 举报
回复 1
回调 -- 实际就是作为函数参数。

实现观察者模式

解耦-- Form1打开Form2,Form2变化通知Form1.函数调用的话Form2需要知道Form1.委托则不需要知道。

110,556

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧