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

PropertyInfo.GetValue抛出TargetException:对象与目标类型不匹配

问题:反射读取行属性时抛出TargetException错误

我想要读取每一行row的所有值,代码实现如下:

internal class ExcelTable<T> : IExcelTable where T : IExcelTableRow
{
    void Foo(){
        var props = typeof(T).GetProperties().ToList();
        for (int r = 0; r < Rows.Count; r++)
        {
            IExcelTableRow row = Rows[r];
            foreach (var p in props)
            {
                // 第一个属性{Int32 Id}时抛出错误
                var v = p.GetValue(row); 
            }
        }
    }
}

运行时抛出以下错误:

System.Reflection.TargetException: 'Object does not match target type.'

当前T的实际类型为ExcelTranscationLogRow(实现了IExcelTableRow接口),该类定义如下:

internal class ExcelTranscationLogRow : IExcelTableRow
{
    public int Id { get; set; }                         // 3619     
    public TransactionType TransactionType { get; set; }// TransactionType.Execution
    public string Identifier { get; set; }              // "Placeholder"
    public TransactionStatus Status { get; set; }       // LogType.Success
    public LogType LogType { get; set; }                // TransactionStatus.Trace
    public string Log { get; set; }                     // "Getting KOT and CPR"
    public DateTime TimeStamp { get; set; }             // {05-07-2022 19:06:38}
}

但另一个IExcelTableRow的实现类ExcelTransactionRow却能正常运行:

internal class ExcelTransactionRow : IExcelTableRow
{
    public int Id { get; set; }
    public string Identifier { get; set; }
    public TransactionStatus Status { get; set; }
    public DateTime StartTime { get; set; }
    public DateTime? EndTime { get; set; }
}

解决方案

问题根源

错误核心是反射使用的属性信息(来自T类型)与传入的目标对象类型不匹配:
你通过typeof(T).GetProperties()获取了T(如ExcelTranscationLogRow)的属性信息,但代码中row被声明为IExcelTableRow接口类型,且Rows集合可能混入了非T类型的实例;或者T被错误指定为IExcelTableRow接口而非具体实现类,导致反射逻辑混乱。

具体修复方案

1. 强制将行转换为T类型

在读取行时,直接将IExcelTableRow类型的对象转换为泛型参数T,确保目标对象类型与反射使用的属性信息所属类型一致:

void Foo(){
    var props = typeof(T).GetProperties().ToList();
    for (int r = 0; r < Rows.Count; r++)
    {
        // 转换为T类型,确保类型匹配
        T row = (T)Rows[r];
        foreach (var p in props)
        {
            var v = p.GetValue(row); 
        }
    }
}

2. 修正Rows集合的类型

将Rows的类型从List<IExcelTableRow>改为List<T>,这样从集合中取出的元素直接是T类型,从根源避免类型不匹配问题:

internal class ExcelTable<T> : IExcelTable where T : IExcelTableRow
{
    // 将Rows改为List<T>类型
    public List<T> Rows { get; set; }

    void Foo(){
        var props = typeof(T).GetProperties().ToList();
        for (int r = 0; r < Rows.Count; r++)
        {
            T row = Rows[r];
            foreach (var p in props)
            {
                var v = p.GetValue(row); 
            }
        }
    }
}

3. 确认泛型参数的正确性

实例化ExcelTable<T>时,确保传入的泛型参数是具体的实现类(如ExcelTranscationLogRow),而非IExcelTableRow接口。如果传入接口类型,typeof(T).GetProperties()只能获取接口定义的属性,无法访问具体类的扩展属性,会导致反射逻辑不符合预期。


内容的提问来源于stack exchange,提问作者Theodor349

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 20:35:31