2012-09-06 64 views
14

我想使用反射動態地設置一個值爲嵌套屬性的類。任何人都可以幫助我做到這一點。如何使用C#反射將Vaues設置爲嵌套屬性。

我有一個類Region像下面。

public class Region 
{ 
    public int id; 
    public string name; 
    public Country CountryInfo; 
} 

public class Country 
{ 
    public int id; 
    public string name; 
} 

我有一個Oracle數據讀取器來提供參考光標的值。

,這將給我作爲

ID,姓名,COUNTRY_ID,COUNTRY_NAME

我可以能夠通過下面的值賦給Region.Id,Region.Name。

FieldName="id" 
prop = objItem.GetType().GetProperty(FieldName, BindingFlags.Public | BindingFlags.Instance); 
prop.SetValue(objItem, Utility.ToLong(reader_new[ResultName]), null); 

而對於嵌套屬性,我可以通過讀取字段名來創建一個實例來爲下面的賦值賦值。

FieldName="CountryInfo.id" 

if (FieldName.Contains('.')) 
{ 
    Object NestedObject = objItem.GetType().GetProperty(Utility.Trim(FieldName.Split('.')[0]), BindingFlags.Public | BindingFlags.Instance); 

    //getting the Type of NestedObject 
    Type NestedObjectType = NestedObject.GetType(); 

    //Creating Instance 
    Object Nested = Activator.CreateInstance(typeNew); 

    //Getting the nested Property 
    PropertyInfo nestedpropinfo = objItem.GetType().GetProperty(Utility.Trim(FieldName.Split('.')[0]), BindingFlags.Public | BindingFlags.Instance); 

    PropertyInfo[] nestedpropertyInfoArray = nestedpropinfo.PropertyType.GetProperties(); 
    prop = nestedpropertyInfoArray.Where(p => p.Name == Utility.Trim(FieldName.Split('.')[1])).SingleOrDefault(); 

    prop.SetValue(Nested, Utility.ToLong(reader_new[ResultName]), null); 
    Nestedprop = objItem.GetType().GetProperty(Utility.Trim(FieldName.Split('.')[0]), BindingFlags.Public | BindingFlags.Instance); 

    Nestedprop.SetValue(objItem, Nested, null); 
} 

上述指定值爲Country.Id

但是因爲我每次創建實例時都無法獲得先前的Country.Id值,如果我選擇Next Country.Name。

有人可以告訴我們可以給objItem(that is Region).Country.IdobjItem.Country.Name分配數值。這意味着如何將值分配給嵌套屬性,而不是每次創建實例和分配。

在此先感謝。

+1

http://stackoverflow.com/questions/1954746/using-reflection的可能的複製-in -c-sharp-to-get-properties-of-an-nested-object –

回答

35

你應該使用Country屬性來獲取國家,然後PropertyInfo.SetValue使用Id屬性被調用PropertyInfo.GetValue設置對國家的ID。

因此,像這樣:

public void SetProperty(string compoundProperty, object target, object value) 
{ 
    string[] bits = compoundProperty.Split('.'); 
    for (int i = 0; i < bits.Length - 1; i++) 
    { 
     PropertyInfo propertyToGet = target.GetType().GetProperty(bits[i]); 
     target = propertyToGet.GetValue(target, null); 
    } 
    PropertyInfo propertyToSet = target.GetType().GetProperty(bits.Last()); 
    propertyToSet.SetValue(target, value, null); 
} 
+0

謝謝親愛的..它的工作就像一個魅力.. :-) – Sravan

+0

爲什麼這被接受爲答案,它會拋出一個nullref,因爲GetValue )如果目標沒有實例化,它將返回null,這將導致一行後面的異常河 –

1

獲取巢性質如Developer.Project.Name

private static System.Reflection.PropertyInfo GetProperty(object t, string PropertName) 
      { 
       if (t.GetType().GetProperties().Count(p => p.Name == PropertName.Split('.')[0]) == 0) 
        throw new ArgumentNullException(string.Format("Property {0}, is not exists in object {1}", PropertName, t.ToString())); 
       if (PropertName.Split('.').Length == 1) 
        return t.GetType().GetProperty(PropertName); 
       else 
        return GetProperty(t.GetType().GetProperty(PropertName.Split('.')[0]).GetValue(t, null), PropertName.Split('.')[1]); 
      } 
+0

該解決方案存在一個主要缺陷,它不適用於通用列表。 例如,您提供FirstObject.MyList [0] .MyValue將僅會因爲它忽略[0]第一個實例而崩潰 –