如何在运行时已知类型的情况下调用C#泛型扩展方法?
问题:运行时已知类型时调用泛型扩展方法
我定义了如下C#泛型扩展方法:
public static T Get<T>(this DataRow row, string columnName) { if (row == null || string.IsNullOrWhiteSpace(columnName) || row.IsNull(columnName)) if (typeof(T) == typeof(string)) return (T)(object)string.Empty; else return default(T); else { if (row[columnName].GetType() == typeof(T)) return row.Field<T>(columnName); else { return (T)Convert.ChangeType(row[columnName], typeof(T)); } } }
尝试在运行时已知类型的场景下调用该方法,代码如下:
obj = new K(); var props = obj.GetType().GetProperties(); for (int i = 0; i < props.Length; i++) { if (row.Table.Columns.Contains(props[i].Name)) { // props[i].SetValue(obj, row[prop]); props[i].SetValue(obj, row.Get<props[i].PropertyType>(props[i].Name)); } }
但编译报错:
Compiler Error CS0019: 运算符“operator”无法应用于“type”和“type”类型的操作数
请问如何在运行时已知类型的情况下调用这个泛型扩展方法?我试过相关解决方案但无效,怀疑是扩展方法的原因。
解决方案
泛型方法的类型参数必须在编译时确定,而props[i].PropertyType是运行时才能获取的Type实例,因此直接用它作为泛型参数会编译失败。扩展方法本质是静态类中的静态方法,你可以通过反射实现运行时调用,步骤如下:
- 定位扩展方法所在的静态类,获取泛型方法的定义;
- 根据当前属性的类型,构造具体的泛型方法实例;
- 调用该方法(注意扩展方法的第一个参数是目标
DataRow对象)。
修改后的代码示例:
obj = new K(); var props = obj.GetType().GetProperties(); // 替换为你定义扩展方法的静态类的Type var extensionClass = typeof(DataRowExtensions); // 获取Get<T>方法的泛型定义 var genericMethodDef = extensionClass.GetMethod("Get", new[] { typeof(DataRow), typeof(string) }); foreach (var prop in props) { if (row.Table.Columns.Contains(prop.Name)) { // 生成对应属性类型的泛型方法 var targetMethod = genericMethodDef.MakeGenericMethod(prop.PropertyType); // 调用方法:第一个参数为null(静态方法),第二个参数是扩展方法的参数列表(row + 列名) var value = targetMethod.Invoke(null, new object[] { row, prop.Name }); prop.SetValue(obj, value); } }
注意点
- 务必将
typeof(DataRowExtensions)替换为你实际存放Get<T>方法的静态类类型; - 如果存在方法重载,调用
GetMethod时可能需要指定BindingFlags(如BindingFlags.Public | BindingFlags.Static)来精准匹配; - 建议添加异常捕获逻辑,处理类型转换失败等运行时异常。
内容的提问来源于stack exchange,提问作者b0bik
相关产品推荐
相关产品推荐

