通过类型名称和方法名称字符串调用静态类上的方法

32

我应该如何在已知类名和方法名的情况下调用静态类上的方法呢?

例如:

已知 System.EnvironmentGetFolderPath,我想使用Reflection来调用Environment.GetFolderPath()

5个回答

49

只是

Type.GetType(typeName).GetMethod(methodName).Invoke(null, arguments);

其中typeName是类型的名称字符串,methodName是方法的名称字符串,而arguments则是一个包含要调用该方法所需参数的对象数组。


2
哇,好的,没错那行得通——我不知道 Type.GetType——只需确保静态类名被命名空间完全限定。 - George Mauer
@GeorgeMauer 如果没有命名空间怎么办? - Furkan Gözükara
@MonsterMMORPG Unity3d?我从未尝试过,但你可以尝试a)根本不使用命名空间或b)“global::NameOfClass”。另外,它可能只是一个单独的“:”。我记不清了。 - George Mauer
如果你正在尝试从字符串内部调用自己的静态类函数,就像我一样(例如:在Program.cs中有很多函数的控制台应用程序,并且您想要一个变量来控制要调用哪个函数),您可以在Main()中使用typeof(Program).GetMethod($"F{functionNumber}").Invoke(null, null);,并使用名为functionNumber的变量来调用它们,方法名称为F1(),F2(),F3()... - Youkko

6

首先,您需要通过反射迭代程序集获取类型。

请参考此链接了解详情:http://msdn.microsoft.com/en-us/library/system.reflection.propertyinfo.aspx

或者使用:

Assembly.GetType

一旦您掌握了类型,就可以使用反射或其他方法迭代成员。
MethodInfo method = typeof(MyClass).GetMethod("MyMethod");

当您想调用方法时,您可以使用 MethodInfo.Invoke 并传递参数来调用该方法。


MyClass是公共的,没有内部静态类的方式? - Kiquenet
@Kiquenet 内部静态类应该使用 MethodInfo methodInfo = typeof(InternalStaticClassName).GetMethod("PrivateMethodNameYouWantToCall", BindingFlags.NonPublic | BindingFlags.Static);,然后调用它时传递 null 作为目标对象和一个包含所需参数的对象数组。 - Ryan

3
System.Reflection.Assembly info = typeof(System.Environment).Assembly;

Type t = info.GetType("System.Environment");
MethodInfo m = t.GetMethod("GetFolderPath");

object result = m.Invoke(null, arguments);

3
你在这里做的是对名为Environment的类型进行反射,并使用GetPropertyGetGetMethod方法来获取Environment.CurrentDirectory属性的get方法,如下所示:
var getMethod = typeof(Environment).GetProperty("CurentDirectory", BindingFlags.Public | BindingFlags.Static).GetGetMethod();
var currentDirectory = (string)getMethod.Invoke(null, null);

调用属性的get方法返回其值,相当于:

var value = Environment.CurrentDirectory;

1

以下是您需要执行的基本概述:

  1. 扫描当前AppDomain中的所有对象-找到与您所知道的类名匹配的对象
  2. 获取该对象上具有您所知道的名称的静态方法
  3. 动态调用它。

编辑:如果您不知道静态类的命名空间,则此方法可行。否则,请使用Daniel Brückner的解决方案,因为它更简单。


我认为你仍然需要扫描AppDomain - 如果你只能创建一个类的实例,这将是动态语言。 - George Mauer
2
这可能是反射过程中正在发生的事情的字面描述,但我认为这个答案对OP没有帮助,因为它没有实际演示或解释如何使用.NET框架API来执行你所概述的步骤。 - Crippledsmurf
没错,我不知道这个 - 如果您不知道或不想键入命名空间,这仍然很有用,但在99%的情况下,请使用Type.GetType。 - George Mauer
如果没有命名空间会怎样? - Furkan Gözükara
@MonsterMMORPG 它仍将在应用程序域中,因此如果您正在扫描,则应该可以工作。 - George Mauer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接