用reflection调用静态方法

我在命名空间mySolution.Macros有几个静态类,如

 static class Indent{ public static void Run(){ // implementation } // other helper methods } 

所以我的问题是如何在reflection的帮助下调用这些方法?

如果方法不是静态的,那么我可以这样做:

 var macroClasses = Assembly.GetExecutingAssembly().GetTypes().Where( x => x.Namespace.ToUpper().Contains("MACRO") ); foreach (var tempClass in macroClasses) { var curInsance = Activator.CreateInstance(tempClass); // I know have an instance of a macro and will be able to run it // using reflection I will be able to run the method as: curInsance.GetType().GetMethod("Run").Invoke(curInsance, null); } 

我想保持我的类静态。 我将如何能够做类似的静态方法?

总之,我想调用命名空间mySolution.Macros中的所有静态类的所有Run方法。

作为MethodInfo.Invoke状态的文档,静态方法的第一个参数被忽略,所以你可以传递null。

 foreach (var tempClass in macroClasses) { // using reflection I will be able to run the method as: tempClass.GetMethod("Run").Invoke(null, null); } 

正如注释所指出的那样,在调用GetMethod时,您可能希望确保该方法是静态的:

 tempClass.GetMethod("Run", BindingFlags.Public | BindingFlags.Static).Invoke(null, null); 

通过付出一次创build委托的代价(也没有必要实例化类来调用静态方法),真的可以真正地优化代码。 我做了一些非常相似的事情,我只是在一个辅助类的帮助下将一个委托caching到“Run”方法:-)。 它看起来像这样:

 static class Indent{ public static void Run(){ // implementation } // other helper methods } static class MacroRunner { static MacroRunner() { BuildMacroRunnerList(); } static void BuildMacroRunnerList() { macroRunners = System.Reflection.Assembly.GetExecutingAssembly() .GetTypes() .Where(x => x.Namespace.ToUpper().Contains("MACRO")) .Select(t => (Action)Delegate.CreateDelegate( typeof(Action), null, t.GetMethod("Run", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public))) .ToList(); } static List<Action> macroRunners; public static void Run() { foreach(var run in macroRunners) run(); } } 

这样做更快。

如果您的方法签名与Action不同,您可以将Action中的type-casts和typeofreplace为任何所需的Action和Funcgenericstypes,或声明您的Delegate并使用它。 我自己的实现使用Func漂亮的打印对象:

 static class PerttyPrinter { static PrettyPrinter() { BuildPrettyPrinterList(); } static void BuildPrettyPrinterList() { printers = System.Reflection.Assembly.GetExecutingAssembly() .GetTypes() .Where(x => x.Name.EndsWith("PrettyPrinter")) .Select(t => (Func<object, string>)Delegate.CreateDelegate( typeof(Func<object, string>), null, t.GetMethod("Print", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public))) .ToList(); } static List<Func<object, string>> printers; public static void Print(object obj) { foreach(var printer in printers) print(obj); } }