为何说C#中的delegate是类型安全的可管理的

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为何说C#中的delegate是类型安全的可管理的相关的知识,希望对你有一定的参考价值。

为何说C#中的delegate是类型安全的可管理的,
特别是相对于C语言中的指针而言。期盼您给个比较透彻的说明。
谢谢。

delegate是类型化了的函数指针,它主要应用于回调。

学习c++的对函数指针都不回陌生,它是一个保存了函数地址的变量,但除了地址,它没有包含任何额外的信息,如参数的个数、参数类型和函数的返回地址等,所以函数指针是非类型安全的。而delegate对回调提供了类型的安全性,从而使我们在处理回调等问题的时候可以更加优美的面向对象的方式来编写代码,并且在CLR的内部对delegate的操作提供了许多支持(如delegate链表),简化了我们常用的操作。

在使用delegate的过程中,首先要定义一个delegate的类型,如:

public delegate void SomeFunction(Object a,int i,...);

note:它是一个类的定义,可以放在任何地方,此类型定义了此delegate所接收的函数的样式:返回void,参数列表...

然后,为了使用,要定义类SomeFunction的一个实例:

public SomeFunction instance;

接着,我们就可以往这个delegate实例中放“符合规范”的函数(可以为实例函数和静态函数)。

instance +=new SomeFunction(someObject.SomeMethod);

其中someObject为某类的一个实例,它的方面SomeMethod符合此委托的规范要求,否则将编译报错。

最后,可以直接调用instance实例来实现对someObject的SomeMethod的回调。

instance(...);

##########################

只是从上面的实现中,貌似看不出delegate真正存在的价值,但实际上delegate增加了对链的支持,我们可以象下面这样应用:

instance +=new SomeFunction(someObject.SomeMethod);

instance +=new SomeFunction(anotherObject.anotherMethod);

...

然后调用instance(...),可以同时激发所有注册自里面的回调函数。

这是怎样实现的,首先要研究delegate内在的结构,在每个delegate里面包括了三个字段:

target ——》指向回调函数所属的对象实例(对于实例方法来言)

method ——》指向回调函数

prev ——》指向另外一个delegate 实例

通过prev就可以比较方便的实现delegate对链的支持。

CLR定义了Delegate.Combine和Delegate.Remove静态方法实现对链表的操作。
参考技术A 哦!
太专业了 有点看不懂了~
学习ing

通过IL分析C#中的委托事件FuncActionPredicate之间的区别与联系

一直以来都是对于事件与委托比较混淆,而且不太会用。找了个时间,总结了一下,感觉清晰了很多。

先说一下个人理解的结论吧:

      delegate是C#中的一种类型,它实际上是一个能够持有对某个方法的引用的类。

     delegate声明的变量与delegate声明的事件,并没有本质的区别,事件是在delegate声明变量的基础上包装而成的,类似于变量与属性的关系(在IL代码中可以看到每一个delegate声明的事件都对应是私有的delegate声明的变量),提升了安全性。

      Action 与Func:这两个其实说白了就是系统定义好的Delegate,他有很多重载的方法,便于各种应用情况下的调用。他在系统的System命名空间下,因此全局可见。

首先了解一下, ILDasm中图标含义:  

   

该图来自:http://www.cnblogs.com/zery/p/3366175.html

委托创建步骤:

1、用delegate关键字创建一个委托,包括声明返回值和参数类型
2、使用的地方接收这个委托
3、创建这个委托的实例并指定一个返回值和参数类型匹配的方法传递过去


一、事件与委托


新建一个事件委托测试项目:EventDelegateTest

具体代码如下:

<span style="font-size:14px;"><span style="font-size:14px;">namespace EventDelegateTest
{
    public class TestClass
    {
        public delegate int delegateAction();
        public event delegateAction OnActionEvent;
        public delegateAction daNew;
    }
}</span></span>
编译代码后,使用 Visual Studio 2010自带的ILDASM.EXE:


打开该dll,可以看到如下信息:


从上图可以看出如下几点信息:

以上是关于为何说C#中的delegate是类型安全的可管理的的主要内容,如果未能解决你的问题,请参考以下文章

通过IL分析C#中的委托事件FuncActionPredicate之间的区别与联系

C# 多线程初级汇总

C#委托(delegateActionFuncpredicate)和事件

C#中代表DELEGATE的作用是啥

C#网络编程一:C#网络编程常用特性

C#委托使用详解(Delegates)