运行时加载程序集后无法获取指定Method问题求助
反射调用静态方法时GetMethod返回null的问题排查
我最近在尝试用反射加载外部程序集并调用指定方法,写了这段代码:
var assemblyLoaded = Assembly.LoadFile(absolutePath); var type = assemblyLoaded.GetType("CreateContactPlugin.Plugin"); var instance = Activator.CreateInstance(type); var methodInfo = type.GetMethod("Execute", new Type[] { typeof(System.String)}); if (methodInfo == null) { throw new Exception("No such method exists."); }
对应的被调用程序集代码是这样的:
namespace CreateContactPlugin { public class Plugin { static bool Execute(string contactName){ bool contactCreated = false; if (!String.IsNullOrWhiteSpace(contactName)) { //process } return contactCreated; } } }
我已经成功加载了程序集和Type,调试时能在type.DeclaredMethods数组里看到这个Execute方法,但调用GetMethod始终返回null,这到底哪里操作有误?
问题原因&解决办法
嗨,这个坑我之前踩过!问题出在两个关键点上:
默认
GetMethod重载不搜索静态方法
你用的Type.GetMethod(string name, Type[] types)重载,默认的绑定标志是BindingFlags.Public | BindingFlags.Instance——只会找公共实例方法,完全不会去扫描静态方法,哪怕方法明明存在,也会返回null。多余的实例创建操作
静态方法不需要类实例就能调用,你写的Activator.CreateInstance(type)完全是无用功,还平白浪费了资源。
给你两个靠谱的解决方式:
方式一:指定正确的绑定标志
修改GetMethod的调用,加上明确的绑定标志,告诉反射要找公共静态方法:
var methodInfo = type.GetMethod( "Execute", BindingFlags.Public | BindingFlags.Static, new Type[] { typeof(string) } );
如果担心继承层级的问题,也可以加上BindingFlags.FlattenHierarchy,确保能找到父类的静态方法(这里虽然用不上,但加上更稳妥):
var methodInfo = type.GetMethod( "Execute", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy, null, new Type[] { typeof(string) }, null );
方式二:遍历DeclaredMethods筛选(备用方案)
如果对绑定标志拿不准,也可以直接遍历你已经看到的DeclaredMethods数组,手动筛选目标方法:
using System.Linq; // 需要引用Linq var methodInfo = type.DeclaredMethods.FirstOrDefault(m => m.Name == "Execute" && m.IsStatic && m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == typeof(string) );
额外提醒:调用静态方法的正确姿势
找到MethodInfo之后,调用的时候第一个参数传null就行,因为静态方法不需要实例:
if (methodInfo != null) { var result = (bool)methodInfo.Invoke(null, new object[] { "TestContactName" }); // 处理返回结果 }
内容的提问来源于stack exchange,提问作者Hubert Solecki
相关产品推荐
相关产品推荐

