所以在过去的一小时里,我一直试图在VB.NET中使用Dynamic Method来调用调用类中的sub。
我几乎没有运气。首先,在尝试按照MSDN(http://msdn.microsoft.com/en-us/library/ms228971.aspx)中的示例时,我无法将该方法设为Sub并且根本不返回任何内容只是想调用另一种方法。
例如
Private Sub FirstMethod()
Dim methodArgs As Type() = {}
Dim MyNewMethod As New DynamicMethod("MyNewMethod", Nothing, methodArgs, GetType(Crux).Module)
Dim il As ILGenerator = MyNewMethod.GetILGenerator()
il.Emit(OpCodes.Call, OtherMethod)
il.Emit(OpCodes.Ret)
End Sub
Private Sub OtherMethod()
MsgBox("This is some other method!")
End Sub
问题是,我不希望它返回任何东西,我只是想让它调用OtherMethod(),我想在我的代码中调用动态方法(通过委托)。 MSDN根本没有真正的帮助,我找不到任何甚至试图解释我想做的事情的方法。
非常感谢任何帮助。
答案 0 :(得分:1)
为什么不尝试使用linq表达式并将它们编译为委托。 它比旧时尚反射更容易。发明。
class Demo {
public void Foo() {
var instance = new Demo();
var method = Expression.Call(Expression.Constant(instance), instance.GetType().GetMethod("Bar"));
var del = Expression.Lambda(method).Compile();
del.DynamicInvoke();
}
public void Bar() {
Console.WriteLine("Bar");
}
}
答案 1 :(得分:0)
DynamicMethod
并不是动态调用方法,而是动态构建方法,就像在运行时构建完整的方法体一样。
如果您想调用某个方法,只需在已有的Invoke
上使用MethodInfo
方法即可。对于没有参数的void方法,只需
var type = this.GetType();
var method = type.GetMethod("OtherMethod");
...
method.Invoke(this, null); // call this.OtherMethod()
现在,如果你想将其封装在Delegate
中,你可以使用
var action = (Action) Delegate.CreateDelegate(typeof(Action), this, "OtherMethod");
action(); // call this.OtherMethod()
我在这里选择了Action作为委托类型,但您可以使用任何兼容的委托类型。
Delegate.CreateDelegate
有几个重载可以帮助您,包括MethodInfo
的重载,因此您可以使用反射来获取正确的方法信息,以及调用CreateDelegate
制作你想要的类型的代表。
请注意,如果在编译时知道要调用的方法,则可以跳过整个反射事件,让编译器为您完成工作:
Action action = this.OtherMethod; // using a so-called method group
Action action = () => this.OtherMethod(); // using a lambda
Action action = delegate { this.OtherMethod(); } // using an anonymous method