c#执行一个字符串作为代码

这是我想要做的,我知道它可以用perl,php,python和java,但我正在使用c#

我该怎么做:

public void amethod(string functionName) { AVeryLargeWebServiceWithLotsOfMethodsToCall.getFunctionName(); } 

我想将functionName传递给方法,我希望它如上所述执行。

怎么做到这一点?

我需要ANTLR或任何其他工具吗?

谢谢。

您可以通过Reflection按名称执行方法。 您需要知道类型以及方法名称(可以是当前对象的类型,或不同对象上的方法,或静态类型)。 它看起来像你想要的东西:

 public void amethod(string functionName) { Type type = typeof(AVeryLargeWebServiceWithLotsOfMethodsToCall); MethodInfo method = type.GetMethod(functionName, BindingFlags.Public | BindingFlags.Static); method.Invoke(null,null); // Static methods, with no parameters } 

编辑以回应评论:

听起来你真的想从这个方法中得到一个结果。 如果是这种情况,假设它仍然是服务上的静态方法(这是我的猜测,根据你写的内容),你可以这样做。 MethodInfo.Invoke将直接将方法的返回值作为Object返回,因此,例如,如果您返回一个字符串,则可以执行以下操作:

 public string amethod(string functionName) { Type type = typeof(AVeryLargeWebServiceWithLotsOfMethodsToCall); MethodInfo method = type.GetMethod(functionName, BindingFlags.Public | BindingFlags.Static); object result = method.Invoke(null,null); // Static methods, with no parameters if (result == null) return string.Empty; return result.ToString(); // Could also be return (int)result;, if it was an integer (boxed to an object), etc. } 

在c#中执行一个字符串就好像它是代码一样,但它并不漂亮或简单。 它也被认为是不良的做法和不安全(你可能也应该在动态语言中避免它)。

相反,做这样的事情:

 public void amethod(Action actionParam) { actionParam(); } 

现在,在您的情况下,您想要调用Web服务。 因为最终归结为xml,你有几个选择:

  • 绕过内置系统以调用Web服务,并使用正确的名称在xml中的正确位置创建自己的Web请求。
  • 为服务中的每个方法创建委托,以便通过reflection传递。

你是说AVeryLargeWebServiceWithLotsOfMethodsToCall是你想要调用名为functionName的方法的对象的实例吗? 如果是这样:

 MethodInfo method = AVeryLargeWebServiceWithLotsOfMethodsToCall.GetType().GetMethod(functionName); method.Invoke(AVeryLargerWebServiceWithLotsOfMethodsToCall, null); 

或者AVeryLargeWebServiceWithLotsOfMethodsToCall是一个要调用名为functionName的静态方法的类型? 如果是这样:

 MethodInfo method = typeof(AVeryLargeWebServiceWithLotsOfMethodsToCall).GetMethod(functionName); method.Invoke(null, null); 

它可以使用reflection来完成。 但是,我相信你需要一个对象引用来配合它。

这里的例子

 Type t = this.GetType(); MethodInfo method = t.GetMethod("showMessage"); method.Invoke(this, null); 

或者,您可以使用Action或其他一些委托来传递对要调用的函数的引用。

 public void amethod(Action function) { function(); } 

你为什么不使用.NET Remoting? 它正是为此而制造的。

一个完全不同的解决方案是使用CSharpCodeCompiler类。

下面是一些实用程序方法,它们可以处理作为字符串传递的类和实例方法调用,以及可选的args和varargs。

这不是生产代码。 它似乎有效,至少有这些微不足道的例子。

 class Program { static void Main(string[] args) { double alpha = Math.Sin(1.0); int beta = alpha.CompareTo(1.0); Console.WriteLine("{0} {1}", alpha, beta); double gamma = (double)CallClassMethod("System.Math.Sin", 1.0); int delta = (int)CallInstanceMethod(gamma, "CompareTo", 1.0); Console.WriteLine("{0} {1}", gamma, delta); string a = "abc"; string x = "xyz"; string r = String.Join(",", a, x); string s = r.Replace(",", ";"); Console.WriteLine("{0} {1}", r, s); string t = (string)CallClassMethod("System.String.Join", ",", new String[] { a, x }); // Join takes varargs string u = (string)CallInstanceMethod(t, "Replace", ",", ";"); Console.WriteLine("{0} {1}", t, u); Console.ReadKey(); } static object CallClassMethod(string command, params object[] args) { Regex regex = new Regex(@"(.*)\.(\w*)"); Match match = regex.Match(command); string className = match.Groups[1].Value; string methodName = match.Groups[2].Value; Type type = Type.GetType(className); List argTypeList = new List(); foreach (object arg in args) { argTypeList.Add(arg.GetType()); } Type[] argTypes = argTypeList.ToArray(); MethodInfo method = type.GetMethod(methodName, argTypes, null); return method.Invoke(null, args); } static object CallInstanceMethod(object instance, string methodName, params object[] args) { Type type = instance.GetType(); List argTypeList = new List(); foreach (object arg in args) { argTypeList.Add(arg.GetType()); } Type[] argTypes = argTypeList.ToArray(); MethodInfo method = type.GetMethod(methodName, argTypes, null); return method.Invoke(instance, args); } }