C#中能否创建存储不同类型val值的SQLValue泛型类列表?
问题分析与解决方案
首先得指出你代码里的几个明显问题:
- 你定义的
SQLValue<T>是泛型类,不能直接写成List<SQLValue>——泛型类必须指定具体的类型参数,比如SQLValue<string>,否则编译器会报错。 - 你实例化对象时写错了,应该是
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
相关产品推荐
相关产品推荐

