这是我想要做的,我知道它可以用perl,php,python和java,但我正在使用c#
我该怎么做:
public void amethod(string functionName)
{
AVeryLargeWebServiceWithLotsOfMethodsToCall.getFunctionName();
}
我想将functionName传递给方法,我希望它能像上面一样执行。
如何做到这一点?
我是否需要ANTLR或任何其他工具?
感谢。
答案 0 :(得分:7)
您可以通过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.
}
答案 1 :(得分:5)
在c#中执行一个字符串就好像它是代码一样,但它并不漂亮或简单。它也被认为是不良的做法和不安全(你可能也应该在动态语言中避免它)。
相反,做这样的事情:
public void amethod(Action actionParam)
{
actionParam();
}
现在,在您的情况下,您想要调用Web服务。因为最终归结为xml,你有几个选择:
答案 2 :(得分:4)
您是说AVeryLargeWebServiceWithLotsOfMethodsToCall
是要在其上调用名为functionName
的方法的对象的实例?如果是这样的话:
MethodInfo method = AVeryLargeWebServiceWithLotsOfMethodsToCall.GetType().GetMethod(functionName);
method.Invoke(AVeryLargerWebServiceWithLotsOfMethodsToCall, null);
或者AVeryLargeWebServiceWithLotsOfMethodsToCall
是一个要调用名为functionName
的静态方法的类型?如果是这样的话:
MethodInfo method = typeof(AVeryLargeWebServiceWithLotsOfMethodsToCall).GetMethod(functionName);
method.Invoke(null, null);
答案 3 :(得分:3)
可以使用反射来完成。但是,我相信你需要一个对象引用来配合它。
来自here
的示例Type t = this.GetType();
MethodInfo method = t.GetMethod("showMessage");
method.Invoke(this, null);
或者,您可以使用Action
或其他某个委托来传递对您要调用的函数的引用。
public void amethod(Action function)
{
function();
}
答案 4 :(得分:1)
为什么不使用.NET Remoting?它就是为此而制作的。
完全其他的解决方案是使用CSharpCodeCompiler类。
答案 5 :(得分:0)
以下是一些实用程序方法,它们可以处理作为字符串传递的类和实例方法调用,并带有可选的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<Type> argTypeList = new List<Type>();
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<Type> argTypeList = new List<Type>();
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);
}
}