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

C#中能否创建存储不同类型val值的SQLValue泛型类列表?

问题分析与解决方案

首先得指出你代码里的几个明显问题:

  1. 你定义的SQLValue<T>是泛型类,不能直接写成List<SQLValue>——泛型类必须指定具体的类型参数,比如SQLValue<string>,否则编译器会报错。
  2. 你实例化对象时写错了,应该是new SQLValue<T>(...)而不是new List<SQLValue>(...),这明显是笔误啦。

回到你的核心需求:创建一个能容纳不同val类型的SQLValue实例列表,这完全可行,但需要调整实现方式,下面给你几个常用的方案:

方案一:用非泛型基类/接口(最推荐,兼顾类型安全和灵活性)

先定义一个非泛型的接口或抽象类,让泛型SQLValue<T>继承它,这样就能用基类型的列表来存储各种泛型实例:

// 定义非泛型接口,统一暴露公共属性和取值方法
public interface ISQLValue
{
    string nam { get; set; }
    string typ { get; set; }
    object GetValue(); // 提供统一的取值入口
}

// 让泛型类实现这个接口
public class SQLValue<T> : ISQLValue
{
    public string nam { get; set; }
    public string typ { get; set; }
    public T val { get; set; }

    // 实现接口的取值方法,把泛型T转成object
    public object GetValue()
    {
        return val;
    }
}

然后创建列表并添加元素:

List<ISQLValue> lst = new List<ISQLValue>();
lst.Add(new SQLValue<string> { nam = "PlayerName", typ = "string", val = "Bot1" });
lst.Add(new SQLValue<bool> { nam = "Ally", typ = "bool", val = true });
lst.Add(new SQLValue<int> { nam = "Levl", typ = "int", val = 2 });

这个方案的好处是:

  • 保留了每个SQLValue<T>实例的编译时类型安全
  • 可以通过GetValue()统一获取值,再根据typ字段转换回具体类型(比如(string)item.GetValue())

方案二:直接用SQLValue<object>(最简单,但类型安全较弱)

因为object是所有.NET类型的基类,你可以直接把泛型参数指定为object,这样列表就能容纳任意类型的val:

List<SQLValue<object>> lst = new List<SQLValue<object>>();
lst.Add(new SQLValue<object> { nam = "PlayerName", typ = "string", val = "Bot1" });
lst.Add(new SQLValue<object> { nam = "Ally", typ = "bool", val = true });
lst.Add(new SQLValue<object> { nam = "Levl", typ = "int", val = 2 });

这个方案的优点是不用修改原有的SQLValue<T>类,但缺点是:

  • 失去了编译时的类型检查,比如你可能不小心把int类型的val放到typ为string的实例里,编译器不会报错
  • 取出val时需要手动转换类型,容易出现运行时转换错误

方案三:用List<dynamic>(灵活但风险高,不推荐)

如果你不想修改原类,也可以用dynamic类型的列表:

List<dynamic> lst = new List<dynamic>();
lst.Add(new SQLValue<string> { nam = "PlayerName", typ = "string", val = "Bot1" });
lst.Add(new SQLValue<bool> { nam = "Ally", typ = "bool", val = true });
lst.Add(new SQLValue<int> { nam = "Levl", typ = "int", val = 2 });

dynamic会绕过编译时类型检查,运行时才解析成员调用,虽然灵活,但很容易因为拼写错误、类型不匹配导致运行时异常,除非是特殊场景,否则不建议用这种方式。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:00:22