用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); } }