让我们分解一下:
首先,反编译 Rx v2.0.3 似乎没有Observable.FromEvent<TEventHandler, TEventHandlerArgs>(add, remove)方法,我碰巧躺在身边的 Rx v 1.1 也没有。我将假设您的意思是我能找到的最接近的匹配项,即:
public static IObservable<TEventArgs> FromEvent<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler)
查看 Rx 1.1 的反编译源代码(2.0 源代码已经把所有架构宇航员都放在了我们身上,并且充满了间接性,这使得它更难理解)使用反射器进行反编译的实际代码片段是这样的:
Action<TEventArgs> o = new Action<TEventArgs>(observer.OnNext);
TDelegate d = CreateDelegate<TDelegate>(o,
typeof(Action<TEventArgs>).GetMethod("Invoke"));
addHandler(d);
所以,问题:
CreateDelegate 如何创建一个签名委托 (obj, args),该委托绑定到操作上的签名 (args) 调用方法?obj去哪儿了?
我不确定我的理解是否完全正确,但似乎这个问题具体是如何CreateDelegate<TDelegate>(o, typeof(Action<TEventArgs>).GetMethod("Invoke")产生一个只有args参数的方法 -o对象会发生什么?
发生的事情是,是的,o对象被传递object firstArgument给内部 .NET 框架方法。
public static Delegate CreateDelegate(Type type, object firstArgument, MethodInfo method, bool throwOnBindFailure)
此方法“绑定” firstArgument 基本上是this返回方法的指针。在内部,它将在委托对象内的某处存储对 firstArgument 的引用。我们看不到它的内部,因为它是一个内部的 .NET 实现细节,所以它可以做各种奇怪的事情,并在它喜欢的地方打破规则。
感觉有点像可能有一个开放的行动代表,我们正在从 CreateDelegate 强制“this”成为“firstArguemnt”,并允许 args 失败。如果是这样感觉有点脏?
是的,这几乎就是正在发生的事情。这就是该CreateDelegate功能的设计目的。
除了它变得比那更脏。CreateDelegate简单地返回一个类型的对象Delegate——我们在方法 args 等上没有类型安全性——然后代码将其转换为 a——这是TDelegate有效的,因为委托是特殊的,您可以将其转换为具有相同“形状”的任何函数类型. 如上所述,它是一个内部 .NET 实现细节,因此它可以做各种奇怪的事情 :-)