Observable.FromEvent& CreateDelegate param映射

时间:2012-11-02 18:53:34

标签: c# delegates system.reactive

我正在研究

的实施
Observable.FromEvent<TEventHandler, TEventHandlerArgs>(add, remove)

我正在努力掌握它是如何运作的。让我们说TEventHandler是标准:

public delegate void EventHandler(object sender, EventArgs e);
然后令我困惑的代码是:

TEventHandler d = (TEventHandler) Delegate.CreateDelegate(
    typeof (TEventHandler),
    (object) new Action<EventArgs>(observer.OnNext),
    typeof (Action<EventArgs>).GetMethod("Invoke"));

(n.b我将此通用代码专门用于此特定示例实例。)

CreateDelegate如何创建一个签名委托(obj,args),该委托绑定到动作上的签名(args)调用方法? obj去哪儿了?

感觉有点像在行动中有一个开放的代表,我们正在强迫'this'从CreateDelegate成为'firstArguemnt'并允许args通过。如果这样感觉有点脏?

1 个答案:

答案 0 :(得分:1)

让我们分解一下:

首先,反编译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实现细节,所以它可以做各种奇怪的事情并打破它所喜欢的规则。

  
    

感觉有点像在行动中有一个开放的代表,我们正在强迫'this'从CreateDelegate成为'firstArguemnt'并允许args通过。如果这样感觉有点脏?

  

是的,这正是发生的事情。这就是CreateDelegate函数的目的 除了它比这更脏。 CreateDelegate只返回类型为Delegate的对象 - 我们在方法args上没有类型安全等等 - 然后代码将其转换为TDelegate - 这是有效的,因为委托是特殊的,您可以将其强制转换为具有相同“形状”的任何函数类型。如上所述,它是一个内部.NET实现细节,所以它可以做各种奇怪的事情: - )