当前位置:首页 > Windows程序 > 正文

C#委托(Delegate)学习日记

2021-03-28 Windows程序

在.NET平台下,委托类型用来定义和响应应用程序中的回调。事实上,.NET委托类型是一个类型安全的对象,指向可以以后调用的其他方法。和传统的C++函数指针不同,.NET委托是内置支持多路广播和异步方法调用的对象。

委托类型包含3个重要信息:

它所调用的方法的名称

该方法的参数

该方法的返回值

1.定义一个委托类型

// 这个委托可以指向任何传入两个整数,返回整数的方法
public delegate int BinaryOp(int x,int y);

创建一个委托类型时,需要使用delegate关键字。当C#编译器处理委托类型时,它先自动产生一个派生自System.MulticastDelegate的密封类。

通过ildasm.exe来查看BinaryOp委托,如下图

编译器是如何确切的定义 Invoke(),BeginInvoke(),EndInvoke() 的呢?让我们看看下面这段代码:

sealed class BinaryOp : System.MulticastDelegate {   public int Invoke(int x,int y);   public IAsyncResult BeginInvoke(int x,int y,AsyncCallback cb,object state);   public int EndInvoke(IasyncResult result); }

Invoke() 方法定义的参数和返回值完全匹配BinaryOp委托的定义。

BeginInvoke() 成员签名的参数也基于BinaryOp委托;但BenginInvoke()方法将总是提供最后两个参数(AsyncCallback,object),用于异步方法的调用。

EndInvoke() 方法的返回值与初始的委托声明相同,总是以一个实现了IasyncResult接口的对象作为其唯一的参数。

我们再定义一个 带有 out/ref 参数的委托类型如下:

public delegate string MyOtherDelegate(out bool a,ref bool b,int c);

试想一下,产生的代码还和上面一样吗?好。

sealed class MyOtherDelegate: System.MulticastDelegate {   public string Invoke(out bool a,ref bool b,int c);   public IAsyncResult BeginInvoke(out bool a,ref bool b,int c,AsyncCallback cb,object state);   public stringEndInvoke(out bool a,ref bool b,IasyncResult result); }

我们发现,Invoke() 和 BeginInvoke() 方法的签名不出所料,但 EndInvoke() 略有差异,,其中包括了委托类型定义的所有 out/ref 参数。

2.System.Delegate和System.MulticastDelegate基类

使用关键字创建委托的时候,也就间接的声明了一个派生自System.MulticastDelegate的类。

下面是System.MulticastDelegate部分成员源代码:

public abstract class MulticastDelegate : Delegate { // 用来在内部管理委托所维护的方法列表 private Object _invocationList; private IntPtr _invocationCount; // 返回所指向的方法的列表 public override sealed Delegate[] GetInvocationList() { Contract.Ensures(Contract.Result<Delegate[]>() != null); Delegate[] del; Object[] invocationList = _invocationList as Object[]; if (invocationList == null) { del = new Delegate[1]; del[0] = this; } else { // Create an array of delegate copies and each // element into the array int invocationCount = (int)_invocationCount; del = new Delegate[invocationCount]; for (int i = 0; i < invocationCount; i++) del[i] = (Delegate)invocationList[i]; } return del; } // 重载的操作符 public static bool operator ==(MulticastDelegate d1, MulticastDelegate d2) { if ((Object)d1 == null) return (Object)d2 == null; return d1.Equals(d2); } public static bool operator !=(MulticastDelegate d1, MulticastDelegate d2) { if ((Object)d1 == null) return (Object)d2 != null; return !d1.Equals(d2); } }

MulticastDelegate

下面是System.Delegate部分成员源代码:

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/68931.html