我有一个C#方法,它接受一个字符串作为参数,该字符串包含静态方法的名称,例如
"MyClass.GetData"
是否可以从字符串中传递的值运行该方法?
答案 0 :(得分:12)
是的,您可以使用System.Reflection
CallStaticMethod("MainApplication.Test", "Test1");
public static void CallStaticMethod(string typeName, string methodName)
{
var type = Type.GetType(typeName);
if (type != null)
{
var method = type.GetMethod(methodName);
if (method != null)
{
method.Invoke(null, null);
}
}
}
public static class Test
{
public static void Test1()
{
Console.WriteLine("Test invoked");
}
}
答案 1 :(得分:2)
是您可以使用反射来查找方法并使用适当的参数调用。
答案 2 :(得分:2)
class Test
{
public void Print(int n)
{
Console.WriteLine(n);
}
}
class MainA
{
static void Main()
{
Type t = typeof(Test);
Object obj = new Test();
System.Reflection.MethodInfo m = t.GetMethod("Print");
m.Invoke(obj,new object[]{11});
}
}
答案 3 :(得分:1)
您可以尝试以下方式:
typeof (MyClass).GetMethod (MyClass.GetData) // Assuming get data is the string name.
这会给你一个MethodInfo课程。从那里,您可以使用Invoke方法(使用正确的参数)。
答案 4 :(得分:1)
答案在于反思。 您可以使用反射来获取某种类型的MethodInfo。 (你必须知道它的类型),然后你可以调用它。
但是,您确定没有更好的解决方案来解决您的问题吗?为什么它作为字符串传递?
答案 5 :(得分:1)
Reflection具有您需要的基本工具,但您仍需要自己解析字符串(将其拆分为点并将其一直反映到必要的MethodInfo)。但是,您应该注意到,这种操作的性能比直接方法调用慢几倍(如果不是千分之一或更多)。可以这样做几次,但是如果你打算这么做,你应该考虑重构你的代码,这样就不需要了。
如果确实无法避免这种情况(在大多数情况下你可以),你至少可以通过缓存在某些字典中找到的MethodInfo对象来加速它。这样你就不必每次都反思。
另外,如果您不了解它们,我建议您查找delegates。这可能是你问题的答案。它几乎和直接方法调用一样快。
答案 6 :(得分:1)
在走向反思的道路之前,这就是你要做的事情,确保没有其他更好的方法来实现它。首先检查委托,因为它们可以调用在运行时设置的方法。
所以在这里你要反思:
public void MyFunction()
{
string dotSeparatedParams = "Myclass.Method";
string[] arrayParams = dotSeparatedParams.Split('.');
// since the class was defined in the string, start with loading it
Type classType = Type.GetType(arrayParams[0]);
if( classType == null )
throw new Exception();
// load the reference to the method
MethodInfo mi = classType.GetMethod(arrayParams[1]);
if (mi == null)
throw new Exception();
// call the method
mi.Invoke(null, null);
}
一些注意事项:
答案 7 :(得分:0)
是。唯一的问题是你也需要提供类的命名空间。
哈斯似乎已经钉了很多。因为我输入了它的麻烦..这是我的版本(temp是命名空间,User是classname,Exists是一个公共静态方法。)private static object ExecuteStaticMethod(string method_full_path, object[] args)
{
var tokens = method_full_path.Split('.');
string class_full_name = String.Format("{0}.{1}", tokens[0], tokens[1]);
var class_blueprint = Assembly.GetExecutingAssembly().GetType(class_full_name);
var handle_to_method = class_blueprint.GetMethod(tokens[2], BindingFlags.Default | BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.Public);
return handle_to_method.Invoke(null, args);
}
public static void Main(string[] args)
{
Console.WriteLine( ExecuteStaticMethod("temp.User.Exists", new object[] {"Gishu"} ) ); // prints false
User.Create("Gishu");
Console.WriteLine(ExecuteStaticMethod("temp.User.Exists", new object[] { "Gishu" })); // prints true
}