2012-07-05 30 views
3

我有下面的代碼:我如何將動態字典值轉換爲列表?

List<Type> p1 = new List<Type>(); 
p1.Add(typeof(int)); 
p1.Add(typeof(string)); 
dynamic genericDic = typeof(Dictionary<, >); 
dynamic specificDic1 = genericDic.MakeGenericType(p1.ToArray()); 
dynamic dic1 = Activator.CreateInstance(specificDic1); 
dic1.Add(1, "John"); 
dic1.Add(2, "Smith"); 
dynamic genericLst = typeof(List<>); 
dynamic specificLst = genericLst.MakeGenericType(typeof(string)); 
dynamic list = Activator.CreateInstance(specificLst); 
list.AddRange(dic1.Values.ToList()); 

當我嘗試執行list.AddRange(dic1.Values.ToList());我得到下面的異常

公共成員「ToList」上鍵入'ValueCollection找不到。

堆棧跟蹤:

at Microsoft.VisualBasic.CompilerServices.Symbols.Container.GetMembers(String& MemberName, Boolean ReportErrors) 
    at Microsoft.VisualBasic.CompilerServices.NewLateBinding.ObjectLateGet(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack) 
    at Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateGet(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack) 
    at StyleResearch.DataManagement.DataStream.Business.MonthEndProcess.ConverToLegacyStructureInMemory(List`1 marketDataTypeIds, String tableName, Int32 placeHolderValue) in C:\Style Research\Work\SRDM\trunk\StyleResearch.DataManagement.DataStream.Business\MonthEndProcess.vb:line 1850 
    at StyleResearch.DataManagement.DataStream.UI.DDLMonthEndProcess._Lambda$__6(LegacyStructureDetail legacy) in C:\Style Research\Work\SRDM\trunk\StyleResearch.DataManagement.DataStream.UI\DDLMonthEndProcess.vb:line 1198 
    at System.Threading.Tasks.Parallel.<>c__DisplayClass2d`2.<ForEachWorker>b__23(Int32 i) 
    at System.Threading.Tasks.Parallel.<>c__DisplayClassf`1.<ForWorker>b__c() 

注:我已經VB.NET樣品轉化成C#,但堆棧跟蹤從VB.NET工程

當我做下面的工作原理精絕:

Dictionary<int, string> dic = new Dictionary<int, string>(); 
dic.Add(1, "John"); 
dic.Add(2, "Smith"); 
List<string> lst = new List<string>(); 
lst.AddRange(dic.Values.ToList()); 

回答

2

ToList < T>()是一個擴展方法的IEnumerable < T>。但是,您的dic1.Values是動態類型不是IENumerable < string>所以.net無法找到並使用此擴展方法。您可以嘗試只是簡單的foreach:

foreach (var value in dic1.Values) 
    list.Add(value) 
+0

感謝您的回覆,但我確實知道這種方法。想知道爲什麼它會失敗時,我使用反射創建對象,而不是正常進行時。 – Rajesh 2012-07-05 10:44:18

+2

正如我所說的那樣,因爲動態類型和擴展方法(ToList)。動態不支持擴展方法(http://stackoverflow.com/questions/5311465/extension-method-and-dynamic-object-in-c-sharp) – Nikolay 2012-07-05 10:46:39

3

只投它:

list.AddRange(((IEnumerable<string>)dic1.Values).ToList()); 

此外,您還可以通過動態又來了:

list.AddRange((dynamic)dic1.Values)); 
+0

正如我所理解的使用動態和反射背後的想法是,你在編譯時不知道列表中的元素的類型(IEnumerable ),所以你不能在編譯時投射它。過分的,你可以使用類型列表,沒有反射和動態 – Nikolay 2012-07-05 11:10:38

+0

同意 - 但他已經宣佈上述類型 - 所以,在這種情況下,它是已知的。 – 2012-07-05 15:32:23

0
list.AddRange((IEnumerable<string>)dic.Values)) 

List<string> list = ((IEnumerable<string>)dic.Values).ToList(); 

List<string> list = new List<string>((IEnumerable<string>)dic.Values); 
+0

當我使用上面的代碼時,我得到這個異常:沒有找到類型'ValueCollection'的公共成員'Cast'。 – Rajesh 2012-07-05 10:47:47

+0

這些工作都不是: 'System.Collections.Generic.Dictionary .ValueCollection'不包含'Cast'的定義 – 2012-07-05 10:49:00

+1

@Rajesh:然後嘗試System.Linq.Enumerable。鑄造(輸入)' – abatishchev 2012-07-05 10:49:01

0

嘗試調用不帶擴展功能的語法,即像

Enumerable.ToList ((dynamic) dic1.Values) 

的DLR在運行時不(由於性能原因尋找繼承接口的擴展功能,或者爲了避免歧義,我猜測)。