详解C#委托和事件(二)
当我们使用关键字delegate声明一个自定义委托类型时,实际上是声明了一个该名称的类类型,继承自抽象类System.MulticastDelegate,还包含实例方法Invoke、BeginInvoke、EndInvoke:
public delegate void MyDelegate();
其中的构造函数中第二个参数是native int类型的,这个是什么呢?我们接着看:
我们知道在C#中任何方法都可以直接赋值给签名一致的委托实例,这个过程看似并不合理,按理来说C#中不支持直接获取函数的指针,其实这里是由编译器进行了取址操作,查看IL代码可知:
MyDelegate myDelegate = myObj.MyFunc;
可以看到这里调用了ldftn命令将实例方法MyFunc()的native int类型的非托管指针推到栈中,从而将该方法的指针传到委托的构造函数中;
由于上面的构造函数存在C#中不支持的函数指针类型void(),所以不能在运行时使用Activator类中的方法创建委托实例,但在委托基类Delegate中存在静态方法CreateDelegate()用于动态创建委托实例:
Type delegateType = typeof(MyDelegate); //这里以可访问到的委托类型举例 Delegate @delegate = Delegate.CreateDelegate(delegateType, myObj, "MyFunc"); //@delegate = typeof(MyClass).GetMethod("MyFunc").CreateDelegate(delegateType, myObj); //添加其它委托实例 @delegate = Delegate.Combine(@delegate, otherDelegate); //调用委托 @delegate.DynamicInvoke(); //当指定的委托类型可访问时,可以将委托实例显式转换为指定的委托类型后使用()或Invoke()正常调用 //MyDelegate myDelegate = @delegate as MyDelegate; //myDelegate();
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的认可是我写作的最大动力!
作者:Minotauros
出处:https://www.cnblogs.com/minotauros/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。