使用Reflection获取运行时加载DLL中类的基类DeclaredFields及属性值
问题分析与解决方案
原有代码错误点
- 核心逻辑错误:
GetField("Features").GetType()获取的是FieldInfo反射类本身的类型,而非Features字段存储的实际值、也不是该字段的声明类型,所以后续取DeclaredFields完全不相关。 - 遗漏实例创建步骤:如果
Features是实例成员,需要先创建VpInterface类的实例才能读取成员值,只有静态成员不需要实例。 - 成员类型匹配问题:你给出的
IntegratorFeatures类的成员都是属性(带get/set访问器),不是字段,所以后续读取成员需要用GetProperties而非GetFields。
正确实现代码
先引用必要命名空间:using System.Reflection;
// 1. 加载程序集 var assembly = Assembly.LoadFile(dllFile); // 2. 获取VpInterface类型 var vpInterfaceType = assembly.DefinedTypes.FirstOrDefault(x => x.Name == "VpInterface"); if (vpInterfaceType == null) { // 自定义找不到VpInterface类的处理逻辑 return; } // 3. 创建VpInterface实例(如果Features是静态成员则跳过这步,后续传null即可) var vpInstance = Activator.CreateInstance(vpInterfaceType); // 4. 从VpInterface的基类获取Features成员 // 注意:如果Features是属性就保留以下代码,是字段就把GetProperty替换为GetField var featuresMember = vpInterfaceType.BaseType.GetProperty("Features", BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); if (featuresMember == null) { // 自定义找不到Features成员的处理逻辑 return; } // 5. 读取Features的实际值 object featuresValue = featuresMember is PropertyInfo prop ? prop.GetValue(vpInstance) : ((FieldInfo)featuresMember).GetValue(vpInstance); if (featuresValue == null) { // 自定义Features未赋值的处理逻辑 return; } // 6. 读取IntegratorFeatures所有属性值 Type featuresType = featuresValue.GetType(); foreach (var property in featuresType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { string propertyName = property.Name; object propertyValue = property.GetValue(featuresValue); // 此处可自定义对属性名、属性值的处理逻辑 }
后续调用DLL内方法的实现指导
- 调用实例方法:先创建对应类的实例,再用
Type.GetMethod()拿到方法信息,最后调用Invoke()传入实例和参数即可,示例:
// 示例:调用VpInterface里的StartCapture方法,入参为int类型端口号 var startCaptureMethod = vpInterfaceType.GetMethod("StartCapture", BindingFlags.Public | BindingFlags.Instance, new[] { typeof(int) }); if (startCaptureMethod != null) { // 无返回值可不接收返回结果 object result = startCaptureMethod.Invoke(vpInstance, new object[] { 8080 }); }
- 调用静态方法:不需要创建实例,
Invoke第一个参数传null即可。 - 重载方法匹配:如果有多个同名方法,
GetMethod要传入准确的参数类型数组才能匹配到正确的重载。 - 非公开成员访问:如果要访问私有字段、属性、方法,只需要在
BindingFlags里加上BindingFlags.NonPublic即可。
内容的提问来源于stack exchange,提问作者Jonathan Hansen
相关产品推荐
相关产品推荐

