2010-03-19 123 views
8

我当前项目中的一个数据结构需要存储各种类型的列表(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; 
} 

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

+0

你可以发布一个简单但完整的程序来演示你的问题吗? – dtb 2010-03-19 20:18:19

回答

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

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

这将工作,直到我必须对列表执行任何操作,或者在列表插入到主列表中后,必须从列表中检索元素时才能使用。 有没有什么简单的方法可以告诉什么类型的IList是? – themarshal 2010-03-19 21:24:09

+0

@themarshal没有不真的。要真正检查的唯一方法是使用'as'操作符来转换为受支持的类型并对其进行操作 – JaredPar 2010-03-19 21:52:23

+0

我终于想出了一种方法来跟踪插入的列表类型。究其原因都一直得到解读为一个字符串列表中,因为当我是基于类型创建的列表中,“整数”类型的被错误生成列表。哎呀! – themarshal 2010-03-19 22:30:02

2

我意识到这是一个古老的问题,但.NET 4给了我们另一种解决方法。 如果你想要一个列表,其中X是另一个列表,y是任何类型呢?

换句话说,一个List>你可能会尝试对象,但是你会永远试图将某些东西转换回原来的类型,如上所述。

因此,这是一种罕见的情况,可以使用新的动态数据类型。 当然,它可以让你打破类型安全,但在这种情况下,因为我们总是要处理某种列表,所以公平地说它将具有“.Count”属性。

因此,像:

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); 

因此,使用动态允许我们删除该类型的安全检查。许多开发人员都反对使用动态。我实际上决定主动寻找一些关于不同类型列表的内容,然后来到这里。所以我为自己的问题添加了自己的解决方案。它实际上被用作测试数据的列表,其中外部列表​​是参数名称的列表,以及用于测试的值的集合9内容列表)。这些参数是不同的,我不希望在源代码创建期间不断从对象转换回我知道的类型。我发现这是一个方便的解决方案。

+0

你的代码甚至不编译! – Arvand 2017-07-29 15:25:56