惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
D
DataBreaches.Net
C
Check Point Blog
雷峰网
雷峰网
小众软件
小众软件
GbyAI
GbyAI
美团技术团队
P
Proofpoint News Feed
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
罗磊的独立博客
大猫的无限游戏
大猫的无限游戏
WordPress大学
WordPress大学
MyScale Blog
MyScale Blog
The Cloudflare Blog
阮一峰的网络日志
阮一峰的网络日志
Apple Machine Learning Research
Apple Machine Learning Research
Y
Y Combinator Blog
Jina AI
Jina AI
爱范儿
爱范儿
Last Week in AI
Last Week in AI
MongoDB | Blog
MongoDB | Blog
I
InfoQ
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 司徒正美

博客园 - changhai-xuri

[转]VS2005快捷键大全 <转载>C#基础面试题 转载(ASP.NET页面之间传递值的几种方式?) 面试的一些体会 程序之路对我来说有多远呢? 晕!我还是没办法改页面顶部的背景图片 关于开发模式的一点点思考 VB和VSS断绝往来了咋办? JAVA中对象的序列化 Spoolsv占用CPU100%的解决方案 Js文件中调用其它Js函数的方法 设计模式之策略模式探讨初步 设计模式之策略模式在设计一群鸭子中的应用 修改一下博客的式样 软件开发模式--软件开发教父与国内高手论道实录全文 微软公司软件开发模式简介 自己写的使用聚集函数实现多行字串合并处理 (转载)使用自定义聚集函数来实现分组合并字符串 关于ORACLE中插入,更新(MERGE)的使用
C#中的代理(Delegate)
changhai-xuri · 2006-11-24 · via 博客园 - changhai-xuri

C#中的代理(Delegate)

    在学习多线程的过程中,又遇到了一个问题:C#代理.上网查了些资料,对代理有了一个初步的认识,记一点笔记.

    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类派生的(delegateSystem.Delegate的别名)。
2)代理隐含具有sealed属性,即不能用来派生新的类型。
3)代理最大的作用就是为类的事件绑定事件处理程序。
4)在通过代理调用函数前,必须先检查代理是否为空(null),若非空,才能调用函数。(5)在代理实例中可以封装静态的方法也可以封装实例方法。
6)在创建代理实例时,需要传递将要映射的方法或其他代理实例以指明代理将要封装的函数原型(.NET中称为方法签名:signature)。注意,如果映射的是静态方法,传递的参数应该是类名.方法名,如果映射的是实例方法,传递的参数应该是实例名.方法名。
7)只有当两个代理实例所映射的方法以及该方法所属的对象都相同时,才认为它们是想等的(从函数地址考虑)。
8)多个代理实例可以形成一个代理链,System.Delegate中定义了用来维护代理链的静态方法CombionRemove,分别向代理链中添加代理实例和删除代理实例。
9)代理的定义必须放在任何类的外面,如delegate int MyDelegate();而在类的方法中调用MyDelegate d = new MyDelegate(MyClass.MyMethod);来实例化自定义代理的实例。
10)代理三步曲:
a.生成自定义代理类:delegate int MyDelegate();
b.然后实例化代理类:MyDelegate d = new MyDelegate(MyClass.MyMethod);
c
.最后通过实例对象调用方法:int ret = d();