2016-02-18 45 views
1

我有一個複雜的類層次結構:類B是類A的屬性,列表(類C)和類D是類B的屬性等 - 很多層次的親子關係。 層次結構中的某些類具有字符串屬性「foobar」。有些課程沒有。 我有一個類A的實例。我需要找到具有屬性「foobar」的層次結構中的所有對象,並將其值更改爲「qwerty」。 在C#中有一種簡單的方法嗎?C# - 在複雜的類層次結構中查找具有特定名稱屬性的所有對象

public class ClassD 
{ 
    public string fooBar; 
} 
public class ClassC 
{ } 
public class ClassB 
{ 
    public List<ClassC> classCList; 
    public ClassD classDInstance; 
    public string fooBar; 
} 
public class ClassA 
{ 
    public ClassB classBInstance; 
} 
+0

你的意思是屬於「[XyzAttribute]」還是別的? – stuartd

+0

類似的東西: '公共類D類 {公共字符串FooBar的;} 公共類ClassC {} 公共類ClassB的 { 公開名單 ClassCList; public ClassD classDInstance; 公共字符串FooBar; } public class ClassA { public ClassB ClassBInstance; }' –

+0

你可以在問題中添加編輯嗎?作爲評論不可讀。 – stuartd

回答

2

它看起來像你想具有給定名稱更改屬性的值

這是非常醜陋的,但可能給你一些想法如何完成你想要使用reflection什麼:

static void Set<T>(dynamic obj, string property, T value) { 
    //Iterate through the fields on your object. Can change this to properties or do both. 
    foreach (var field in obj.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance)) { 
     var fieldValue = field.GetValue(obj); 

     //If we have a collection, then iterate through its elements. 
     if (field.FieldType.GetInterface("System.Collections.IEnumerable") != null && !(fieldValue is string) && fieldValue != null) 
      foreach (var item in fieldValue) SetField<T>(item, property, value); 
     //If field name and type matches, then set. 
     else if (field.Name == property && field.FieldType == typeof(T)) field.SetValue(obj, value); 
    } 
} 

就叫做如下:

Set(obj, "fooBar", "qwerty"); 

注意,這僅時刻遍歷字段,因爲這是您的類設置的方式(公共字段,而不是屬性)。如果要包含屬性,可以將其更改爲使用屬性,或合併字段和屬性,並遍歷both

同樣,我不是說要使用這種方法,但可能會給你一些想法。

2

你可以使用反射,雖然我不是這樣的大粉絲,我想這是最簡單的方法來實現你所需要的。

下面的代碼不是很漂亮,但希望能給你一個想法。

private static void replaceFoobar(object obj) 
    { 
     if (obj == null) 
      return; 

     const BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.GetProperty | BindingFlags.Instance; 
     FieldInfo[] members = obj.GetType().GetFields(bindingFlags); 

     if (!members.Any()) 
      return; 

     foreach (var item in members) 
     { 
      if (item.Name == "fooBar" || item.Name == "<fooBar>k__BackingField") 
      { 
       item.SetValue(obj, "qwerty"); 
      } 
      else 
      { 
       object value = item.GetValue(obj); 

       if (value != null && value is IEnumerable) 
       { 
        foreach (var itemE in ((IEnumerable)value)) 
         replaceFoobar(itemE); 
       } 
       else 
        replaceFoobar(value); 
      } 
     } 
    } 
相關問題