列出具有不同值类型的<t>

时间:2018-05-24 05:05:14

标签: c#

C#。 我有一节课:

public class SQLValue<T> 
{ 
    public string nam { get; set; } 
    public string typ { get; set; } 
    public T val      { get; set; } 
}

现在我要创建

List<SQLValue> lst = List<SQLValue>();

并像这样添加元素:

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

所以我想要一个包含不同类型值val的类列表。这是真的吗?

3 个答案:

答案 0 :(得分:4)

你做不到。

需要一些基本类型。显然,你可以随时使用List<object>, 如果您只想存储SQLValue<T>个实例。

但是,假设您希望根据namtyp属性处理列表项,您可以在此处提取一些基类/接口:

public interface ISQLValue
{
    public string nam { get; set; } 
    public string typ { get; set; } 
    public object val { get; set; }
}

SQLValue<T>这种方式实现它:

public class SQLValue<T> : ISQLValue
{ 
    public string nam { get; set; } 
    public string typ { get; set; } 

    public T val { get; set; } 

    object ISQLValue.val 
    {  
        get { return this.val; }
        set { this.val = (T)value; }
    }
}

并使用List<ISQLValue>存储实例并处理它们:

var sqlValues = new List<ISQLValue>
{
    new SQLValue<string> { nam="PlayerName", typ="string", val="Bot1" }
    new SQLValue<bool> { nam="Ally", typ="bool", val=true }
    new SQLValue<int> { nam="Levl", typ="int", val=2 }
};

foreach (var value in sqlValues)
{
    Console.WriteLine($"nam = {value.name}, typ = {value.typ}, val = {value.val}");
}

即,在某些批处理的情况下,将使用ISQLValue。但是,如果您知道T的{​​{1}},则可以将其投放到ISQLValue并使用SQLValue<T>代替T val

答案 1 :(得分:1)

不,你不能这样做,因为泛型最终被转换成单独的类型。

  

当首次使用值类型作为参数构造泛型类型时,运行时会创建专用泛型类型,并在MSIL的相应位置替换所提供的参数或参数。 为每个用作参数的唯一值类型创建一次专用泛型类型

     

参考:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/generics-in-the-run-time

所以SQLValue<int>SQLValue<bool>实际上是两种不同的类型。因此,您无法使用

创建List<T>
var lst = new List<SQLValue>();

相反,您还必须为T指定类型SQLValue。因此,允许这样的事情,

var lst = new List<SQLValue<bool>>();

或者,

var lst = new List<SQLValue<int>>();

此外,在您的代码中,向此类列表添加元素的语法不正确。例如,如果您正在使用列表,

var lst = new List<SQLValue<bool>>();

您可以使用以下方法为其添加值:

lst.Add(new SQLValue<bool> {  nam="Ally", typ="bool", val=true });

或者,通过构造函数,如果已定义一个,

lst.Add(new SQLValue<bool> ("Ally", "bool", true ));

构造函数可以是:

public SQLValue(string nam, string typ, T val )
{
    this.nam = nam;
    this.typ = typ;
    this.val = val;
}

答案 2 :(得分:1)

您可以创建自己的类,其中包含所有信息:

class MyClass
{
    public string Name { get; set; }
    public Type PropType { get; set; }
    public object Value { get; set; }
}

然后你可以在其中添加项目:

List<MyClass> list = new List<MyClass>()
{
    new MyClass(){ Name = "name1", PropType = typeof(string), Value = "asdasd" },
    new MyClass(){ Name = "name2", PropType = typeof(bool), Value = true },
    new MyClass(){ Name = "name3", PropType = typeof(int), Value = 11 },

};

然后使用它,例如:

foreach (var item in list)
{
    switch (Type.GetTypeCode(item.PropType))
    {
        case TypeCode.String:
            break;
        case TypeCode.Int32:
            break;
        case TypeCode.Boolean:
            break;
        default:
            throw new NotSupportedException();
    }
}