不同类型的列表列表

时间:2010-03-19 20:15:23

标签: c# generics list

我当前项目中的一个数据结构要求我存储各种类型的列表(String,int,float等)。我需要能够动态存储任意数量的列表,而不知道它们将是什么类型。

我尝试将每个列表存储为object,但是在尝试转换回适当类型时遇到了问题(它将所有内容都识别为List<String>)。

例如:

List<object> myLists = new List<object>();

public static void Main(string args[])
{
    // Create some lists...

    // Populate the lists...

    // Add the lists to myLists...

    for (int i = 0; i < myLists.Count; i++)
    {
        Console.WriteLine("{0} elements in list {1}", GetNumElements(i), i);
    }
}

public int GetNumElements(int index)
{
    object o = myLists[index];

    if (o is List<int>)
        return (o as List<int>).Count;

    if (o is List<String>)                  // <-- Always true!?
        return (o as List<String>).Count;   // <-- Returning 0 for non-String Lists

    return -1;
}

我做错了什么吗?有没有更好的方法来存储各种类型的列表列表,还是有更好的方法来确定某些东西是否是某种类型的列表?

2 个答案:

答案 0 :(得分:10)

类型List<T>继承自非泛型接口IList。由于myList类型中的所有值都绑定了List<T>,因此您可以将它们用作非泛型IList。因此,您可以使用它来大大简化您的逻辑

public int GetNumElements(int index) {
  object o = myLists[index];
  var l = o as IList;
  return l.Count;
}

或者,由于您知道myList中存储的所有值都是List<T>的绑定版本,因此请使用IList作为类型,而不是object。< / p>

List<IList> myLists = new List<IList>();
...
public int GetNumElements(int index) {
  return myList[index].Count;
}

答案 1 :(得分:2)

我意识到这是一个古老的东西,但.NET 4为我们提供了另一种解决方法。 如果你想要一个列表,其中X是另一个列表,y是任何类型,那该怎么办?

换句话说,列表&gt;你可能会尝试使用对象,但是你会永远试图将某些东西归还给它的原始类型,如上所述。

因此,这是一种罕见的情况,可以使用新的动态数据类型。 当然,它允许你打破类型安全,但在这种情况下,因为我们总是会处理某种类型的列表,所以说它会有它的公平性a&#34; .Count&#34;属性。

类似于:

var myMainList = new List<List<dynamic>>();
var myInnerList1 = new List<string> { "A", "B", "C" };
var myInnerList2 = new List<int> { 1, 2, 3, 4, 5 };
myMainList.Add(myInnerList1);
myMainList.Add(myInnerList2);

// when we come to try and read the number of values in the list..
Console.WriteLine("inner list 1 : {0}", myMainList[0].Count);
Console.WriteLine("inner list 2 : {0}", myMainList[1].Count);

因此使用dynamic允许我们放弃类型安全检查。许多开发人员都反对使用动态。我实际上决定积极寻找有关不同类型列表的内容,并来到这里。所以我为自己的问题添加了自己的解决方案。它实际上被用作测试数据列表,其中外部列表​​是参数名称列表,以及要在测试中使用的值的集合9inner列表。每个参数都有所不同,我不想在创建源代码时不断地从对象转换回我知道的类型。我发现这是一个方便的解决方案。