2011-07-08 45 views
2

我有一個項目,它存儲SQL中的值,然後檢索它們進行分析。爲了跟蹤何種類型的值可能會被保存,我創建了一個類大致是這樣的:存儲變量類型並使用它在運行時創建集合

private class DataField 
{ 
    public string FieldName; 
    public string FieldType; 
} 

當被讀取分析值,一個switch語句中使用如下(簡化):

switch (DataField.FieldType) 
{ 
    case "int": 
     List<int> InputData = new List<int>(); 
     // Populate list from DB 
    break; 
    case "bool": 
     List<bool> InputData = new List<bool>(); 
     // Populate list from DB 
    break; 
} 

而不是維護代碼在多個地方,我正在尋找一種方法來擺脫switch語句,但這意味着我需要動態創建基於類型的集合。目前該類型是(天真?)的字符串,但我想我可以改變類改善這樣的:

private class ImprovedDataField 
{ 
    public string FieldName; 
    public Type FieldType; 
} 

,然後動態莫名其妙地創建集合:

Type DataType = typeof(DataField.FieldType); 
List<DataType> InputData = new List<DataType>(); 
// Populate list from DB 

這當然不工作,導致Type or namespace name expected錯誤。

不幸的是,我不是很熟悉Type類,也沒有泛型或匿名類型,因爲我搜索解決方案(似乎沒有什麼合適的)。

如何減少每個switch語句分支中唯一區別是正在生成的變量集合類型的代碼重複?

+0

可能重複(http://stackoverflow.com/questions/2078914/c-sharp-dynamic-generic-type) – nawfal

回答

4

如果要在運行時創建靜態類型的已知類型對象的集合,則需要使用反射。見即this blog entry - 這是創建List<T>解決方案:

public static IList CreateGenericList(Type collectionType) 
{ 
    var listType = typeof(List<>).MakeGenericType(new[] { collectionType}); 
    return (IList) Activator.CreateInstance(listType); 
} 
在你的榜樣

所以:

Type dataType = DataField.FieldType; 
IList inputData = CreateGenericList(dataType); 
// Populate list from DB 
+0

1。我來這裏輸入這個:)。請記住考慮如何抽取「從數據庫填充列表」的步驟。因爲如果你使用switch語句或者其他的東西來實現這個目的,它就會失敗。 – OpticalDelusion

+0

@A .:這非常有幫助,因此我將其標記爲已接受。我通過創建'List '解決了這個問題,其中'MyObject'包含'object'類型,並將Type作爲參數傳遞給檢索數據的方法,實質上將switch語句移動到更小,更易維護的部分。 – JYelton

0

爲什麼你需要一個類型的集合?爲什麼不使用ArrayList? [C#普通動態類型]的

ArrayList list = new ArrayList() 

list.Add(/* value read from database */) 
+0

也許它不需要是一個類型的集合。你能舉個例子說明你的意思嗎? – JYelton

+0

我想他意味着既然你有FieldName(我假設你用它從數據庫中提取數據),你根本不需要知道數據的類型。你可以將數據存入任何東西,不管是ICollection 還是ArrayList。 – OpticalDelusion