[英]C# dynamic generic list
我想創建一個通用的List <>,其類型在運行時聲明。
我可以做到以下幾點,但由於它是動態的,我懷疑有速度懲罰。 我正在為異國情調的數據庫編寫一個包裝器,因此速度至關重要。
List<dynamic> gdb = new List<dynamic>()
我在動態泛型類型中閱讀了這篇文章 ,但無法讓它發揮作用。 具體來說,該對象不會顯示為List,因此沒有添加方法。
Type ac;
switch (trail[dataPos].Type)
{
case GlobalsSubscriptTypes.Int32:
ac = typeof(System.Int32);
break;
case GlobalsSubscriptTypes.Int64:
ac = typeof(System.Int64);
break;
default:
ac = typeof(System.String);
break;
}
var genericListType = typeof(List<>);
var specificListType = genericListType.MakeGenericType(ac);
var gdb = Activator.CreateInstance(specificListType);
如何讓gdb顯示為以下之一:
List<System.Int32>
List<System.Int64>
List<System.String>
一旦使用了Activator.CreateInstance
,就可以將結果轉換為適當的類型。 您可以使用IList
例如:
var gdb = (IList)Activator.CreateInstance(specificListType);
gdb.Add(1);
請注意,如果您要添加的類型與泛型類型不匹配,則上面會拋出ArgumentException
。
哦, gdb
是正確的類型。 由於您在運行時確定類型,因此編譯器不知道它。 因此,它是靜態類型為object
,並不顯示Add
方法。 您有幾個選項可以解決這個問題:
將其轉換為正確的類型:
switch (trail[dataPos].Type) { case GlobalsSubscriptTypes.Int32: ((List<int>) gdb).Add(...); break; ... default: ((List<String>) gdb).Add(...); break; }
轉換為常見的超類型:
((System.Collections.IList) gdb).Add(...);
使用動態調用:
dynamic gdb = Activator.CreateInstance(specificListType); gdb.Add(...);
在您的情況下, gdb
將始終是System.Object
,因為CreateInstance
返回任何類型的對象。
這里有幾個選項 - 您可以將其轉換為IList
(非泛型),因為您知道List<T>
實現此接口,並使用IList.Add
。
或者,您可以將其聲明為dynamic
,並使用動態綁定:
dynamic gdb = Activator.CreateInstance(specificListType);
這將使您編寫代碼,就好像它是相應類型的List<T>
,並且調用將在運行時通過動態綁定進行綁定。
List<dynamic>
編譯與List<object>
完全相同的類型,而不是類型化List<int>
速度懲罰,例如,超過裝箱值類型。 但是如果你要向IList施放你仍然會有拳擊懲罰FYI。
你可能遇到麻煩的是調用Activator
(一種反射方法),因為直接調用構造函數可能會慢得多。
這有什么關系嗎? 除非您實際運行配置文件,否則您將無法知道,因為它始終取決於您的實際使用情況。
我最好的客人,你真正想做的是:
IList gdb;
switch (trail[dataPos].Type)
{
case GlobalsSubscriptTypes.Int32:
gdb = new List<int>();
break;
case GlobalsSubscriptTypes.Int64:
gdb = new List<long>();
break;
default:
gdb = new List<string>();
break;
}
此外,如果你真的需要在沒有拳擊的情況下進行操作,可以使用通用幫助方法完成所有工作:
switch (trail[dataPos].Type)
{
case GlobalsSubscriptTypes.Int32:
return Helper<int>(trail[dataPos]);
case GlobalsSubscriptTypes.Int64:
return Helper<long>(trail[dataPos]);
default:
return Helper<string>(trail[dataPos]);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.