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是您可以得到的最低级别,反射方法已经为您做了大量的工作。