2011-10-15 39 views
5

我需要更改List<*DynamicType*>類型的動態變量的Capacity屬性。 的問題是,如果不指定變量類型,而不是正確List<*DynamicType*>,我所能做的最好是將其轉換爲IListActivator回報object -casted變量:轉換爲動態類型變量的通用列表

DynamicTypeBuilder builder = new DynamicTypeBuilder() { ... }; 
Type dataType = builder.GenerateType(...); 
Type listDataType = typeof(List<>).MakeGenericType(dataType); 
IList list = (IList)Activator.CreateInstance(listDataType); 

一些搜索我只找到一個破解後:

dynamic dynamicList = list; 
dynamicList.Capacity = dataRowsCount; 

雖然這在我的情況下是可以接受的,但我不知道是否有另一種方法可以做到這一點。

回答

3

也許,這是簡單的:

object list = Activator.CreateInstance(listDataType, 
    new object[]{dataRowsCount}); 

哪些應該使用正確的構造函數?

泛型和反射確實是一種組合。這裏的dynamic破解不會比通過反射(魔術字符串作爲文字,vs未驗證的屬性成員)設置它更難,而dynamic是內部優化和緩存(每類型),所以我不會有問題。如果你需要做的不僅僅是一個屬性的更多,你也可以使用dynamic翻轉成一個通用的方法,以儘量減少醜:

void Evil<T>(List<T> list, int capacity) { 
    list.Capacity = capacity; 
    // do other stuff 
} 
... 
dynamic list = Activator.CreateInstance(listDataType); 
Evil(list, dataRowsCount); 

將調用泛型方法與正確的T。不值得僅爲1個成員,但它可能對更復雜的場景有用。

+0

忘記了那個構造函數。因爲我只需要設置這個屬性,所以這樣做非常簡單。我也喜歡你的建議,使用泛型方法來「投射」IList對象,非常好。 –

+0

順便說一句,雖然我可能做錯了什麼,但在我的情況下將'Activator.CreateInstance()'的結果分配給'generic'變量將不起作用,因爲'list.Add(*動態創建的dataType對象*)'導致異常,並將'list'預先轉換爲'IList'。 –

+0

@Dmitry確定,然後投射到'IList'。在示例中,我沒有這麼做,僅僅是因爲我正在說明在示例*中執行操作的最小值,並且該示例沒有添加(...)' –

4

你可以用反射做到這一點:

var capacityProperty = listDataType.GetProperty("Capacity"); 
capacityProperty.SetValue(list, dataRowsCount, null); 

另一種是寫它確實在靜態類型的方式,你想要的一切,一個通用的方法,並調用與反思代替。這可以是確保你只需要一個反射的便捷方式。

+0

不錯,沒有想過反射的原因。當我再次處理動態\泛型時,我會記住這一點。 –