You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在运行时已知类型的情况下调用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实例,因此直接用它作为泛型参数会编译失败。扩展方法本质是静态类中的静态方法,你可以通过反射实现运行时调用,步骤如下:

  1. 定位扩展方法所在的静态类,获取泛型方法的定义;
  2. 根据当前属性的类型,构造具体的泛型方法实例;
  3. 调用该方法(注意扩展方法的第一个参数是目标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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 01:45:24