为何Delegate和MulticastDelegate类中无BeginInvoke、EndInvoke方法定义?
为什么自定义委托能调用BeginInvoke/EndInvoke,但基类里找不到定义?
这确实是个挺有意思的细节——我刚接触.NET的时候也纠结过这个问题!
其实真相是:BeginInvoke和EndInvoke并不是定义在Delegate或MulticastDelegate基类中的固定方法,而是CLR在编译阶段为每个自定义委托类型动态生成的专属方法。
背后的原因
每个委托的签名都是独一无二的:不同的委托可能有不同的参数类型、参数数量和返回值类型。如果在基类里预先定义通用的BeginInvoke/EndInvoke,根本无法适配所有委托的签名需求。所以CLR会根据你定义的委托的具体签名,自动生成匹配的异步方法:
BeginInvoke的参数会包含委托本身的所有输入参数,再加上AsyncCallback回调和object状态参数,返回IAsyncResult;EndInvoke则接收IAsyncResult参数,返回委托定义的返回值类型。
举个例子,假设你定义了这样一个委托:
public delegate string MyCalculationDelegate(int inputNum, string inputText);
CLR会自动为它生成如下的BeginInvoke和EndInvoke:
// 自动生成的BeginInvoke public IAsyncResult BeginInvoke(int inputNum, string inputText, AsyncCallback callback, object state); // 自动生成的EndInvoke public string EndInvoke(IAsyncResult result);
怎么验证这个机制?
你可以用反射来查看委托类型的方法列表,就能找到这两个动态生成的方法。比如用这段代码:
Type delegateType = typeof(MyCalculationDelegate); MethodInfo[] methods = delegateType.GetMethods(BindingFlags.Public | BindingFlags.Instance); foreach (var method in methods) { Console.WriteLine(method.Name); }
运行后就能看到BeginInvoke和EndInvoke出现在结果里。
补充说明
在.NET Core及更高版本中,异步编程更多使用Task、async/await模式,但这个动态生成BeginInvoke/EndInvoke的机制在传统.NET Framework中是实现委托异步调用的经典方式。
内容的提问来源于stack exchange,提问作者Nagabhushan L
相关产品推荐
相关产品推荐

