2010-03-19 161 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