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

反序列化JSON时使用带约束的C#泛型:rows属性访问及泛型参数报错问题

解决C#泛型JSON反序列化中无法访问子类属性的问题

问题原因

  • 你的GenericCouch类中,TTable的约束仅为TableBase,而TableBase并未定义rows属性,因此反序列化得到的TTable类型变量只能访问TableBase的成员,无法直接访问OrderItemDrugTable<TRow>的rows。
  • 你尝试的JsonSerializer.Deserialize<TTable<TRow>>写法错误,因为TTable是一个具体的类型参数(比如实例化时传入的OrderItemDrugTable<DrugRow>),而非泛型类型定义(如OrderItemDrugTable<>),所以不能为它附加类型参数,这就是编译器报错的核心原因。

解决方案

方案一:通过接口约束关联TTable与TRow

定义包含rows属性的接口,让OrderItemDrugTable<TRow>实现该接口,同时修改GenericCouch的泛型约束,确保TTable实现此接口:

// 定义统一接口
public interface IHasRows<TRow> where TRow : RowBase
{
    List<TRow> rows { get; set; }
}

// 让OrderItemDrugTable实现接口
public class OrderItemDrugTable<TRow> : TableBase, IHasRows<TRow> where TRow : RowBase
{
    public List<TRow> rows { get; set; }
}

// 修改GenericCouch的约束
public class GenericCouch<TRow, TTable> 
    where TRow : RowBase 
    where TTable : TableBase, IHasRows<TRow>
{
    public void DeserializeTable(string result, JsonSerializerOptions options)
    {
        var table = JsonSerializer.Deserialize<TTable>(result, options);
        // 现在可直接访问rows属性
        var targetRows = table.rows;
    }
}

方案二:直接约束TTable为OrderItemDrugTable的子类

如果GenericCouch仅用于处理OrderItemDrugTable及其子类,可直接将TTable的约束设为OrderItemDrugTable<TRow>:

public class GenericCouch<TRow, TTable> 
    where TRow : RowBase 
    where TTable : OrderItemDrugTable<TRow>
{
    public void DeserializeTable(string result, JsonSerializerOptions options)
    {
        var table = JsonSerializer.Deserialize<TTable>(result, options);
        // 直接访问rows属性
        var targetRows = table.rows;
    }
}

方案三:在TableBase中定义抽象rows属性

如果所有TableBase的子类都需要rows属性,可在基类中定义抽象属性,子类实现该属性:

public abstract class TableBase
{
    public abstract List<RowBase> Rows { get; set; }
}

public class OrderItemDrugTable<TRow> : TableBase where TRow : RowBase
{
    public List<TRow> rows { get; set; }

    // 实现基类抽象属性
    public override List<RowBase> Rows
    {
        get => rows.Cast<RowBase>().ToList();
        set => rows = value.Cast<TRow>().ToList();
    }
}

public class GenericCouch<TRow, TTable> 
    where TRow : RowBase 
    where TTable : TableBase
{
    public void DeserializeTable(string result, JsonSerializerOptions options)
    {
        var table = JsonSerializer.Deserialize<TTable>(result, options);
        // 通过基类属性访问,按需转换为TRow类型
        var targetRows = table.Rows.Cast<TRow>().ToList();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 12:46:15