2011-10-28 66 views
1

我正在嘗試使用反射設置對象的屬性。 該屬性是一個ICollection - 如果集合尚未實例化,我想完成此操作。我的問題是,我有問題獲得內部類型將ICollection的通過c#中的反射訪問內部類型的ICollection <SomeInnerClass>#

這是我的課

public class Report(){ 
    public virtual ICollection<Officer> OfficerCollection { get; set; } 
} 

我試圖通過反射來訪問下面定義的「官」類

public class Officer(){ 
    public string Name{ get; set; } 
} 

代碼片斷

Report report = new Report() 

PropertyInfo propertyInfo = report.GetType().GetProperty("OfficerCollection"); 
object entity = propertyInfo.GetValue(report, null); 
if (entity == null) 
{ 
    //How do I go about creating a new List<Officer> here? 
} 
+2

爲什麼你需要使用反射?你的財產已經公開。 – Gabe

+0

這是一個非常簡單的例子;-) –

+0

如果你打算設計一個例子,你應該明確它。在這種情況下,將'Officer'同時作爲類的名稱和該類的實例集合的屬性的名稱是不必要的混淆。 – Gabe

回答

3

給這個一掄:

Report report = new Report(); 

PropertyInfo propertyInfo = report.GetType().GetProperty("Officer"); 
object entity = propertyInfo.GetValue(report, null); 
if (entity == null) 
{ 
    Type type = propertyInfo.PropertyType.GetGenericArguments()[0]; 
    Type listType = typeof(List<>).MakeGenericType(type); 

    var instance = Activator.CreateInstance(listType); 

    propertyInfo.SetValue(...); 
} 
+0

漂亮 - 幾乎正確,我不得不使用Type type = propertyInfo.PropertyType。GetGenericArguments()[0];所以如果你編輯你的答案,我會接受它。謝謝! –

+0

@HugoForte:編輯。很高興爲你效力! –

0

忽略整個設計聽起來很糟糕的問題,我會盡力回答你的問題。您可以通過Type type = ...GetProperty(...).PropertyType找到該酒店的類型。如果類型是具體類型 - 而不是當前的接口 - 那麼可以使用System.Activator.CreateInstance(type, null) - 其中null表示無構造函數參數 - 以創建此具體類型的實例。鑑於你的屬性類型實際上是一個接口,你不知道你是否應該創建一個列表,數組,集合或任何其他類型來滿足這種類型。然後,您需要使用SetValue將實例分配給該屬性,但當然我們無法實現這一目標。

你應該把這些信息重新評估自己的設計,不是靠反射,而是使用通用的參數(看new()約束)和屬性的初始化工作(如果你認爲這是有道理的 - 我們不介意讀者。)

2

首先你必須得到Officer屬性:

var propertyType = propertyInfo.PropertyType; 

然後你提取泛型類型參數:

var genericType = propertyType.GetGenericArguments()[0]; 

來調用後創建一個通用的清單:

var listType = typeof(List<>).MakeGenericType(genericType); 

最後創建泛型列表的新實例:

var listInstance = Activator.CreateInstance(listType); 

和......玩得開心;)

編輯:

有時反射會很高興,但我建議你這樣做:

public class Report() 
{ 
    private ICollection<Officer> officers; 

    public virtual ICollection<Officer> Officer 
    { 
     get 
     { 
      if(officers == null) 
       officers = new List<Officer>(); 

      return officers; 
     } 
     set { officers = value; } 
    } 
} 
+0

感謝您的評論! –