如何通过反射获取字段类型并将其作为泛型类型参数传入方法
解决方案
完全可以实现,核心是调用MethodInfo.MakeGenericMethod()动态构造指定泛型参数的封闭方法,再通过反射调用即可,不需要编译期硬编码泛型参数。
实现步骤
- 先获取
Database.GetData泛型方法的开放定义(未绑定泛型参数的版本) - 遍历
ActivityData的所有字段时,用字段的类型作为泛型参数,构造对应封闭泛型方法 - 调用构造好的方法,将返回值赋值给对应字段即可
完整代码示例
// 先拿到GetData泛型方法的开放定义,注意参数列表要和你实际的GetData方法匹配 MethodInfo getOpenGenericMethod = typeof(Database).GetMethod( "GetData", BindingFlags.Public | BindingFlags.Static, new Type[] { typeof(IDataReader), typeof(string) } ); // 初始化要赋值的目标对象 ActivityData rtn = new ActivityData(); foreach(FieldInfo f in typeof(ActivityData).GetFields()) { // 获取该字段对应的DB列名 var dbAttr = f.GetCustomAttribute<DBAttribute>(); if (dbAttr == null) continue; // 没有标记DBAttribute的字段跳过 // 用当前字段的类型构造封闭泛型方法 Database.GetData<FieldType> MethodInfo closedGenericMethod = getOpenGenericMethod.MakeGenericMethod(f.FieldType); // 调用方法,参数顺序和GetData的入参对应,返回值是object类型 object fieldValue = closedGenericMethod.Invoke(null, new object[] { nReader, dbAttr.ColumnName }); // 给目标对象的对应字段赋值 f.SetValue(rtn, fieldValue); }
注意事项
- 如果
Database.GetData有多个重载,需要调整GetMethod的参数,确保准确匹配到你要调用的泛型重载 - 反射调用的性能确实比直接硬编码调用低不少,只适合测试学习或者低频次调用的场景
- 如果字段是值类型,
Invoke返回的是装箱后的对象,赋值时SetValue会自动处理拆箱,不需要额外操作
内容的提问来源于stack exchange,提问作者Skyhighjinks
相关产品推荐
相关产品推荐

