2009-09-02 21 views
1

我需要能夠通過反射訪問屬性,並且知道此屬性是IEnumerable,請將對象附加到它。通過反射將對象附加到IEnumerable <>

事情是這樣的:

Object o; 
MemberInfo m; 

Array arr; // Except use IEnumerable, may have to take account of value/ref types 
arr = (Array)((PropertyInfo)m).GetValue(o, null); } 

List<o.GetType()> newArr = new List<o.GetType()>(); /* fails */ 
newArr.AddRange(arr); 
newArr.Add(o); 

((PropertyInfo)m).SetValue(o, newArr.ToArray(), null); 

你能幫助我,我要去哪裏錯了:-)

解決方案:

見接受的答案評論。另外(Get the actual type of a generic object parameter)也有幫助。

回答

2

這聽起來像你基本上要求如何基於編譯時未知類型來製作List<T>。爲此,你將不得不使用多一點反思魔法:

Type genericListType = typeof(List<>); 
Type listType = genericListType.MakeGenericType(o.GetType()); 
object listInstance = Activator.CreateInstance(listType); 

這將創建一個List<T>出的運行時類型。

不過說真的,你的代碼就會簡單得多,如果你只是使用ArrayList:

ArrayList list = new ArrayList(arr); 
list.Add(o); 
Array newArray = list.ToArray(o.GetType()); 
+0

感謝指着我在正確的方向。不幸的是,我不認爲我可以編寫一個處理字符串[],列表,List 的屬性的通用解決方案(即使遺漏字典)。問題是,你可以不投以附加,即使我創建了一個IEnumerable 我不能用這個新創建的對象替換類型列表的屬性字段說listInstance到列表。 – 2009-09-02 08:26:12

+1

是否有可能退後一步並考慮您正在解決的整體問題,看看您是否可以利用更符合編譯時間的方法?反思是強大的,但最終會變得複雜而難以維護。 如果你不能改變你正在做的事情,還有一種方法可以支持你提到的一切,它只需要難看的反射代碼。我可能會忘記替換底層引用,只是尋找我可以使用的Add方法(例如,propertyType.GetMethod(「Add」)),然後是數組的特殊情況處理。 – bobbymcr 2009-09-02 15:07:11

+0

這是針對一個數據文件一般映射代碼類,以便反映已是答案。謝謝你,雖然,結合你的想法,這個問題(http://stackoverflow.com/questions/1371347/get-the-actual-type-of-a-generic-object-parameter/1371378#1371378)陣列的處理+幫助:-) – 2009-09-03 04:05:08

4

一旦你有一個IEnumerable類型,使用這樣的追加到它:

public static IEnumerable<T> Append<T>(this IEnumerable<T> original, T next) 
{ 
    foreach (T item in original) yield return item; 
    yield return next; 
} 

public static IEnumerable<T> Append<T>(this IEnumerable<T> original, params T[] next) 
{ 
    foreach (T item in original) yield return item; 
    foreach (T item in next) yield return item; 
} 

public static IEnumerable<T> Append<T>(this IEnumerable<T> original, IEnumerable<T> next) 
{ 
    foreach (T item in original) yield return item; 
    foreach (T item in next) yield return item; 
} 
+0

謝謝你:-) – 2009-09-02 04:53:30

+0

雖然你必須重新命名這些方法追加 2009-09-02 06:01:16

相關問題