【发布时间】:2011-12-14 18:58:48
【问题描述】:
我正在尝试编写一个用于从任意事件触发对方法的调用的类,但我被困住了,因为我根本无法从发出的 MSIL 代码中找到引用“this”的方法。
这个例子应该描述我在寻找什么:
class MyEventTriggeringClass
{
private object _parameter;
public void Attach(object source, string eventName, object parameter)
{
_parameter = parameter;
var e = source.GetType().GetEvent(eventName);
if (e == null) return;
hookupDelegate(source, e);
}
private void hookupDelegate(object source, EventInfo e)
{
var handlerType = e.EventHandlerType;
// (omitted some validation here)
var dynamicMethod = new DynamicMethod("invoker",
null,
getDelegateParameterTypes(handlerType), // (omitted this method in this exmaple)
GetType());
var ilgen = dynamicMethod.GetILGenerator();
var toBeInvoked = GetType().GetMethod(
"invokedMethod",
BindingFlags.NonPublic | BindingFlags.Instance);
ilgen.Emit(OpCodes.Ldarg_0); // <-- here's where I thought I could push 'this' (failed)
ilgen.Emit(OpCodes.Call, toBeInvoked);
ilgen.Emit(OpCodes.Ret);
var sink = dynamicMethod.CreateDelegate(handlerType);
e.AddEventHandler(source, sink);
}
private void invokedMethod()
{
Console.WriteLine("Value of _parameter = " + _parameter ?? "(null)");
// output is always "(null)"
}
}
以下是我设想使用的类的示例:
var handleEvent = new MyEventTriggeringClass();
handleEvent.Attach(someObject, "SomeEvent", someValueToBePassedArround);
(请注意,上面的例子毫无意义。我只是试图描述我在寻找什么。我的最终目标是能够在任意事件触发时触发对任意方法的调用。我'将在我尝试使用 100% MVVM 的 WPF 项目中使用它,但我偶然发现了 [看似] 经典的断点之一。)
无论如何,代码“有效”,只要它在任意事件触发时成功调用“invokedMethod”,但“this”似乎是一个空对象(_parameter 始终为空)。我已经进行了一些研究,但根本找不到任何好的示例,其中“this”被正确传递给从这样的动态方法中调用的方法。
我找到的最接近的示例是 THIS ARTICLE,但在该示例中,可以强制使用动态方法,因为它是从代码调用的,而不是任意事件处理程序。
任何建议或提示将不胜感激。
【问题讨论】:
-
不要使用全局
_parameter并将自定义EventArgs作为参数传递给您的方法。 -
如果您仔细观察,您会发现目标方法('invokedMethod')将从动态构建的任意事件处理程序中调用。因此,事件处理程序可以是诸如“MouseDown”或“SelectedChanged”之类的任何东西。事件处理程序将被传递 EventArgs (或其某些后代),这在这种情况下是无关紧要且毫无用处的。我只需要在触发事件时收到通知,然后使用一堆值(本例中为“参数”),根本无法将其传递到调用链中。这就是为什么我需要目标方法中的“this”值。
-
您是想在 .NET 中创建事件作为一等公民,还是尝试创建某种消息总线?
-
我真的有两个目标。主要目标是能够捕获在 WPF 用户界面中触发的任何事件,并使用它来将值写入底层视图模型数据上下文。第二个目标是学习。
-
你能用C#(不使用IL)编写事件处理程序的代码吗?为什么要在
Attach方法中分配_parameter值?您可以将 cmets 添加到您的代码中吗?谢谢
标签: c# this cil il ilgenerator