【问题标题】:Adding different type of generic objects into generic list将不同类型的通用对象添加到通用列表中
【发布时间】:2011-08-17 06:05:02
【问题描述】:

是否可以将不同类型的通用对象添加到列表中?如下。

public class ValuePair<T>
{        
    public string Name { get; set;}
    public T Value { get; set;                     
}

假设我拥有所有这些对象...

 ValuePair<string> data1 =  new ValuePair<string>();
 ValuePair<double> data2 =  new ValuePair<double>();
 ValuePair<int> data3 =  new ValuePair<int>();

我想将这些对象保存在一个通用列表中。例如

List<ValuePair> list = new List<ValuePair>();

list.Add(data1);
list.Add(data2);
list.Add(data3);

有可能吗?

【问题讨论】:

标签: c# c#-4.0 c#-3.0


【解决方案1】:

一般来说,您必须使用 List&lt;object&gt; 或创建非泛型基类,例如

public abstract class ValuePair
{
    public string Name { get; set;}
    public abstract object RawValue { get; }
}

public class ValuePair<T> : ValuePair
{
    public T Value { get; set; }              
    public object RawValue { get { return Value; } }
}

那么你可以有一个List&lt;ValuePair&gt;

现在,有一个例外:C# 4 中的协变/逆变类型。例如,您可以这样写:

var streamSequenceList = new List<IEnumerable<Stream>>();

IEnumerable<MemoryStream> memoryStreams = null; // For simplicity
IEnumerable<NetworkStream> networkStreams = null; // For simplicity
IEnumerable<Stream> streams = null; // For simplicity

streamSequenceList.Add(memoryStreams);
streamSequenceList.Add(networkStreams);
streamSequenceList.Add(streams);

这不适用于您的情况,因为:

  • 您使用的是泛型类,而不是接口
  • 您无法将其更改为通用协变接口,因为您已经让T“进入”“退出”API
  • 您将值类型用作类型参数,而这些类型不适用于泛型变量(因此 IEnumerable&lt;int&gt; 不是 IEnumerable&lt;object&gt;

【讨论】:

    【解决方案2】:

    除非你有一个非泛型基类型ValuePairValuePair&lt;T&gt; : ValuePair(它也适用于接口),或者使用List&lt;object&gt;。但实际上,这是合理的:

    public abstract class ValuePair
    {
        public string Name { get; set; }
        public object Value
        {
            get { return GetValue(); }
            set { SetValue(value); }
        }
        protected abstract object GetValue();
        protected abstract void SetValue(object value);
    }
    public class ValuePair<T> : ValuePair
    {
        protected override object GetValue() { return Value; }
        protected override void SetValue(object value) { Value = (T)value; }
        public new T Value { get; set; }
    }
    

    【讨论】:

      【解决方案3】:

      不,这是不可能的。在您的情况下,您可以创建一个基类ValuePairValuePair&lt;T&gt; 派生自该基类。取决于你的目的。

      【讨论】:

        【解决方案4】:

        据我所知,这是不可能的。

        行:

        List<ValuePair> list = new List<ValuePair>();
        

        您在示例中写的没有为 T 提供具体类型,这就是问题所在,一旦您通过它,您只能添加该特定类型的对象。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-11-13
          • 1970-01-01
          • 2012-06-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多