C# 如何通过反射和/或ILGenerator.Emit以编程方式调用方法?

C# 如何通过反射和/或ILGenerator.Emit以编程方式调用方法?,c#,reflection,reflection.emit,C#,Reflection,Reflection.emit,假设我有代码,在运行时接收方法调用列表: static void Main(string[] args) { var foo = new Foo(); var code0 = "DoThis()"; foo.DynamicCalls(code0); var code1 = "DoThis(1)"; foo.DynamicCalls(code1); var code2 = $"DoTha

假设我有代码,在运行时接收方法调用列表:

    static void Main(string[] args)
    {
        var foo = new Foo();
        var code0 = "DoThis()";
        foo.DynamicCalls(code0);
        var code1 = "DoThis(1)";
        foo.DynamicCalls(code1);
        var code2 = $"DoThat({"Hey"})";
        foo.DynamicCalls(code2);
        // and so on
    }
如何以编程方式调用这些方法调用

这就是我到目前为止所拥有的,我觉得我错过了一些东西

public class Foo
{
    public void DoThis()
    {
        Console.WriteLine($"Doing this {0}");
    }
    public void DoThis(int count)
    {
        Console.WriteLine($"Doing this {count}");
    }

    public void DoThat(string message)
    {
        Console.WriteLine($"Doing that {message}");
    }

    public void DynamicCalls(string codeToExecute)
    {

        EmitCompileAndExecute(codeToExecute); //how?

        /*
        var targetMethodName = string.Concat(codeToExecute.TakeWhile(z => z != '('));
        var stringArgs = string.Concat(codeToExecute.SkipWhile(z => z != '(')
            .Skip(1)
            .TakeWhile(z => z != ')'))?.Trim()
            .Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

        var methodInfo = this.GetType().GetTypeInfo().GetRuntimeMethods()
            .SingleOrDefault(z => z.Name.Equals(targetMethodName, StringComparison.OrdinalIgnoreCase) 
             & stringArgs.Length == z.GetParameters().Length);


        // mi.Invoke(this, stringArgs); // args need to match type!


        DynamicMethod dm = new DynamicMethod("foo", null, null);
        ILGenerator gen = dm.GetILGenerator();
        foreach (string arg in stringArgs)
        {

        }
        */

    }

}

将方法名和参数作为字符串提供会大大增加解析的难度,因为现在引入了另一个解析问题。您应该将这两种方法分开,这样做会更加容易,即
public void DynamicCalls(string methodName,params object[]args){typeof(Foo).GetMethod(methodName,args.Select(x=>x.GetType()).ToArray()).Invoke(this,args);}
。您可以将其称为
foo.DynamicCalls(“DoThis”,1)
。就这样。在我的用例中,这是对这个方案的有限支持。“Foo”类上的方法签名必须是无歧义的,如示例所示。可以像你概述的那样做。我只是想知道ILGenerateator.Emit是否有一种更优雅的方式来完成它,比如Javascipt中的“eval”之类的。使用ILGenerator会变得更复杂,因为IL是您可以得到的最低级别,反射方法已经为您做了大量的工作。