让我们分解一下:
首先,反编译 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 实现细节,因此它可以做各种奇怪的事情 :-)