Вызов метода в динамическом методе в VB.NET - PullRequest
1 голос
/ 17 декабря 2011

Итак, в течение последнего часа я пытался использовать динамический метод в VB.NET для вызова подпрограммы внутри вызывающего класса.

Мне не повезло с несколькими вещами.Во-первых, пытаясь следовать примеру из 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 на самом деле совсем не помог, и я не могу найти ничего, что даже пытается объяснить способ сделать то, что я хочу.

Любая помощь очень ценится.

Ответы [ 2 ]

1 голос
/ 08 мая 2012

Почему бы вам не попробовать использовать выражения linq и скомпилировать их в делегат. Это проще, чем старомодное отражение.emit.

  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");
    }
}
0 голосов
/ 08 мая 2012

A DynamicMethod на самом деле не о динамическом вызове метода, а о динамическом построении метода, как при создании полного тела метода во время выполнения.

Если вы хотите вызвать метод, вы можете просто использовать метод Invoke на MethodInfo, который у вас уже есть. Что для пустого метода без аргументов просто

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
...