如何将一个通用类存储在列表中而不指定类型?

3

我有以下类:

class Parameter<T>
{
    public string Index { get; set; }
    public T Value { get; set; }
}

我希望您能提供这样一份清单:
class ParameterModel
{
    public List<Parameter<>> Parameters {get;}
}

然后我将会有类似以下的代码:
...
Parameter<> parameter = parameterModel.Parameters.Where(p => p.Index == "AAA");
if (parameter is Parameter<bool>)
{
    ...
}
else if (parameter is Parameter<int>)
{
    ...
}
...

这个问题可以解决,不过您应该使用继承而不是泛型?

提前感谢。


2
这是一个需要使用继承和动态分派的情况。 - user703016
为什么不使用 ParameterModel<T> - Sriram Sakthivel
@SriramSakthivel:请检查Jodrell的响应。 - Ignacio Soler Garcia
3个回答

4

wouldn't

class ParameterModel<T>
{
    public List<Parameter<T>> Parameters { get; }
}

需要完成这个任务吗?


或者您想要不同类型的参数?那么您可以进行以下操作:

public interface IParameter
{
    string Index { get; set; }
    Type ParameterType { get; }
}

public class Parameter<T> : IParameter
{
    public string Index { get; set; }
    public T Value { get; set; }
    public Type ParameterType
    {
        get
        {
            return typeof(T);
        }
    }
}

class ParameterModel
{
    public List<IParameter> Parameters { get; }
}

所以你可以这样做:
var aaaParameter = parameterModel.Parameters.Single(p => p.Index == "AAA");
if (aaaParameter.ParameterType == typeof(bool))
{
    ...
}
else if (aaaParameter.ParameterType == typeof(string))
{
    ...
}

但是,考虑到你所描述的问题的范围,一个简单的字典可能是最好的选择。
var parameterModel = new Dictionary<string, object>();

允许

var aaaParameter = parameterModel["AAA"];
if (aaaParameter is bool)
{
    ...
}
else if (aaaParameter is string)
{
    ...
}

我只需要一个参数模型,因为我需要对参数列表进行建模,无论其后备值类型是什么。当我使用它们时,我会检查类型。 - Ignacio Soler Garcia
第二种方案看起来更好,我会给它一个机会。 - Ignacio Soler Garcia
不能切换类型。需要使用if else链或switch over TypeCode - Sriram Sakthivel
@SoMoS,最后一个选项对我来说看起来很直接。 - Jodrell
@Jodrell 这甚至更糟,is关键字不能与类型一起使用。它需要一个静态的Type(类名)。例如:obj is String - Sriram Sakthivel
啊,现在看起来不错。我应该给你+1个解决方法的数量。 - Sriram Sakthivel

1
您可以这样做 - 简短而简洁:

 public class Parameter
 {
     public string Index { get; set; }
     public dynamic Value { get; set; }
 }

 var param1 = new Parameter() { Index = "qw", Value = 34 };
 var param2 = new Parameter() { Index = "qr", Value = "rere" };

 int val1 = (int)param1.Value;
 string val2 = (string)param2.Value;

获取类型的方法:

  var t1 = param1.Value.GetType();
  var t2 = param2.Value.GetType();

在你的情况下可能是这样的:
 if (param1.Value.GetType() == typeof(int))
 {...}
 else if (param1.Value.GetType() == typeof(string))
 {...}

with a

 List<Parameter> myParams=new List<Parameter>();

1

您可以使用继承。

以下是最近工作中的一个示例:

abstract public class AttributeVariant
{
    string key;
    string name;

    public AttributeVariant(string key, string name)
    {
        this.key = key;
        this.name = name;
    }

    public string GetKey()
    {
        return key;
    }

    public string GetName()
    {
        return name;
    }
}

public class AttributeVariant<T> : AttributeVariant
{
    T value;

    public AttributeVariant(string key, string name, T value = default) : base(key, name)
    {
        this.value = value;
    }

    public object GetValue()
    {
        return value;
    }

    public void SetValue(T value)
    {
        this.value = value;
    }
}

public class AttributeVariant<T, T2> : AttributeVariant<T>
{
    T2 data;

    public AttributeVariant(string key, string name, T value = default, T2 data = default) : base(key, name, value)
    {
        this.data = data;
    }

    public object GetData()
    {
        return data;
    }

    public void SetData(T2 data)
    {
        this.data = data;
    }
}

这样我就可以将泛型类类型存储到一个简单的变量中,而不会有任何问题。以下是我如何使用它们的示例:

static Dictionary<string, AttributeVariant> AttributesList = new Dictionary<string, AttributeVariant>()
{
    { "age", new AttributeVariant<string>("age", "Age") },
    { "arms", new AttributeVariant<string>("arms", "Arms") },
    { "bridge", new AttributeVariant<string>("bridge", "Bridge") },
    { "color", new AttributeVariant<string>("color", "Model") },
    { "condition", new AttributeVariant<string, double>("condition", "Condition") },
    { "full_color", new AttributeVariant<string>("full_color", "Full Color") },
    { "gender", new AttributeVariant<string>("gender", "Gender") },
    { "height", new AttributeVariant<string>("height", "Height") },
    { "lenses", new AttributeVariant<string>("lenses", "Lenses") },
    { "material", new AttributeVariant<string>("material", "Material") },
    { "rim_type", new AttributeVariant<string>("rim_type", "Rim Type") },
    { "shape", new AttributeVariant<string>("shape", "Shape") },
};

你如何迭代AttributesList字典并打印每个条目的"value"字段(及其类型)?即使使用反射,您也不知道类型。更具体地说,在迭代中如何将该“value”字段转换为变量。 - OldBerkay
您可以使用.GetType().GetGenericArguments()检索泛型参数的类型,并相应地调整代码的行为。当然,您必须事先知道如何处理这些类型。如果我想知道我是否有双重或单一泛型参数,我可以计算GetGenericArguments()返回的数组的长度,或者更具体地执行以下操作:.GetType().GetGenericTypeDefinition() == typeof(AttributeVariant<,>) .GetType().GetGenericTypeDefinition() == typeof(AttributeVariant<>) - Guido Belluomo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接