Dan*_*anH 12 c# delegates system.reactive
我正在考虑实施
Observable.FromEvent<TEventHandler, TEventHandlerArgs>(add, remove)
Run Code Online (Sandbox Code Playgroud)
我正在努力把握它是如何运作的.让我们说TEventHandler是标准:
public delegate void EventHandler(object sender, EventArgs e);
Run Code Online (Sandbox Code Playgroud)
那令我困惑的代码是:
TEventHandler d = (TEventHandler) Delegate.CreateDelegate(
typeof (TEventHandler),
(object) new Action<EventArgs>(observer.OnNext),
typeof (Action<EventArgs>).GetMethod("Invoke"));
Run Code Online (Sandbox Code Playgroud)
(我已将此通用代码专门用于此特定示例实例.)
CreateDelegate是如何创建一个签名委托(obj,args)绑定到动作上的签名(args)的调用方法?obj去哪儿了?
感觉有点像在行动中有一个开放的代表,我们正在强迫'this'成为CreateDelegate的'firstArguemnt'并允许args通过.如果这样感觉有点脏?
让我们来分解一下:
首先,反编译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)
Run Code Online (Sandbox Code Playgroud)
查看 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);
Run Code Online (Sandbox Code Playgroud)
那么,问题是:
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)
Run Code Online (Sandbox Code Playgroud)
此方法将firstArgument“绑定”为基本上作为this返回方法的指针。在内部,它将存储对委托对象内某处的firstArgument 的引用。我们无法看到其内部,因为它是内部 .NET 实现细节,因此它可以做各种奇怪的事情并随心所欲地违反规则。
感觉有点像在操作上有一个开放的委托,我们正在将“this”强制为 CreateDelegate 的“firstArguemnt”,并允许参数失败。如果这样感觉有点脏吗?
是的,这几乎正是正在发生的事情。这就是该CreateDelegate函数的设计目的。
但它变得比那更脏。CreateDelegate只是返回一个类型的对象Delegate- 我们在方法参数等上没有类型安全 - 然后代码将其转换为 a TDelegate- 这是有效的,因为委托是特殊的,您可以将其转换为具有相同“形状”的任何函数类型。如上所述,它是一个内部 .NET 实现细节,因此它可以做各种奇怪的事情:-)
| 归档时间: |
|
| 查看次数: |
1197 次 |
| 最近记录: |