5

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

我该怎么做:

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

我想将 functionName 传递给该方法,并且我希望它像上面那样执行。

如何做到这一点?

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

谢谢。

4

6 回答 6

7

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

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将直接将方法的返回值作为对象返回,因此,例如,如果您要返回一个字符串,则可以执行以下操作:

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.
}
于 2009-10-02T19:36:41.717 回答
5

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

相反,请执行以下操作:

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

现在,在您的情况下,您想要调用 Web 服务。由于这最终归结为 xml 无论如何你有几个选择:

  • 绕过用于调用 Web 服务的内置系统,并在 xml 中的正确位置使用正确的名称创建您自己的 Web 请求。
  • 为服务中的每个方法创建委托以传递,可能通过反射。
于 2009-10-02T19:36:05.100 回答
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);
于 2009-10-02T19:35:12.293 回答
3

可以使用反射来完成。但是,我相信您需要一个对象引用才能使用它。

来自这里的示例

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

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

public void amethod(Action function)
{
    function();
}
于 2009-10-02T19:35:47.503 回答
1

为什么不直接使用 .NET Remoting?它正是为此而生的。

一个完全其他的解决方案是使用 CSharpCodeCompiler 类。

于 2009-10-02T22:47:18.880 回答
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);
    }
}
于 2012-06-13T17:22:13.933 回答