2017-04-27 63 views
1

我想使用反射設置對象的變量。使用反射設置變量對象不起作用

對於簡單的對象,這可以工作。 (屬性)

但具有類變量(字段)的對象不起作用。在這裏,我總是得到一個「對象不符合目標類型」的Exeption。

有沒有人在這裏有一個想法如何去?

class Program 
{ 
    static void Main(string[] args) 
    { 
     var genericDataSet = new GenericDataSet<DataObjekt>(); 
     var returnObjekt = genericDataSet.KeepElementsData(); 
    } 
} 

public class DataObjekt 
{ 
    public string Name { get; set; } 
    public ObjektData ModelTyp; 
    public DataObjekt() { ModelTyp = new ObjektData(); } 
} 

public class ObjektData 
{ 
    public string Typ { get; set; } 
    public string Data { get; set; } 
} 

public class GenericDataSet<T> where T : class, new() 
{ 
    public T KeepElementsData() 
    { 
     var item = new T(); 
     //Propertys durchlaufen 
     foreach (var Property in item.GetType().GetProperties()) 
     { 
      item.GetType().GetProperty(Property.Name).SetValue(item, "TestData"); //this works 
     } 

     //Fields durchlaufen 
     foreach (var Field in item.GetType().GetFields()) 
     { 
      foreach (var FieldProperty in item.GetType().GetField(Field.Name).FieldType.GetProperties()) 
      { 
       var data = item.GetType().GetField(Field.Name).FieldType.GetProperty(FieldProperty.Name); 
       data.SetValue(item, "TestData not work", null); // this doesent work 
      } 
     } 
     return item; 
    } 
} 
+0

你爲什麼要叫'item.GetType()getfield命令(Field.Name)',而不是僅僅使用'Field'? (我也敦促你開始遵循.NET命名約定 - 你的本地變量通常是'field'和'fieldProperty'。) –

回答

0

它不工作的原因是因爲你錯了對象上設置值:

data.SetValue(item, "TestData not work", null); 

item沒有這個屬性,其領域有它。
您需要創建該字段的實例(如果其爲null),然後填充其屬性,然後將其設置爲該字段。

下面會爲你工作:

public class GenericDataSet<T> where T : class, new() 
{ 
    public T KeepElementsData() 
    { 
     var item = new T(); 
     //Propertys durchlaufen 
     foreach (var propertyInfo in item.GetType().GetProperties()) 
     { 
      item.GetType().GetProperty(propertyInfo.Name).SetValue(item, "TestData"); //this works 
     } 

     //Fields durchlaufen 
     foreach (var fieldInfo in item.GetType().GetFields()) 
     { 
      object fieldObject = Activator.CreateInstance(fieldInfo.FieldType); 

      // Or if it's already instantiated: 
      // object fieldObject = fieldInfo.GetValue(item); 

      foreach (var fieldProperty in fieldInfo.FieldType.GetProperties()) 
      { 
       fieldProperty.SetValue(fieldObject, "TestData not work", null); // this doesent work 
      } 
      fieldInfo.SetValue(item, fieldObject); 
     } 
     return item; 
    } 
} 
+1

謝謝,這正是我想要做的:) –

0

試試這個:

public T KeepElementsData() 
{ 
    var item = new T(); 
    //Propertys durchlaufen 
    foreach (var property in item.GetType().GetProperties()) 
    { 
     property.SetValue(item, "TestData"); //this works 
    } 

    //Fields durchlaufen 
    foreach (var field in item.GetType().GetFields()) 
    { 
     var value = field.GetValue(item); 
     var type = value.GetType(); 

     foreach (var fieldProperty in type.GetProperties()) 
     { 
      fieldProperty.SetValue(value, "TestData works"); 
     } 
    } 
    return item; 
} 

你要來回PropertyInfo-之間>名稱PropertyInfo->的PropertyInfo的......再加上你是混合的領域item對象..

1

就我所見,這個應該不適用於屬性,因爲你只提供字符串數據,而不是所有的屬性都有字符串類型。無論如何,在你的領域循環爲什麼你有一個嵌套循環?你正在循環每個字段類型的屬性,這是我猜的相當大。所以如果你的字段有字符串類型,你在內循環中遍歷String的所有字段。你應該能夠省略內部循環並且寫出與你的屬性相同的內容。此外,您可以直接設置當前item的屬性值。

var item = new T(); 
//Propertys durchlaufen 
foreach (var property in item.GetType().GetProperties()) 
{ 
    property.SetValue(item, "TestData"); //this works 
} 

//Fields durchlaufen 
foreach (var field in item.GetType().GetFields()) 
{ 
    field.SetValue(item, "TestData"); 
} 
+1

@BRAHIMKamel爲什麼?我已經提到,這些領域並不是所有的字符串,所以當然它不會爲所有人工作,但至少在第一個OP實際要求的是什麼。 – HimBromBeere

+0

@HimBromBeere是的,不僅有屬性的字符串,但爲此我有一個解決方案。 –