2017-04-27 8 views
1

Reflectionを使用してオブジェクトから変数を設定したいとします。反射を使用してオブジェクトから変数を設定できない

単純なオブジェクトの場合、これは機能します。 (プロパティ)

しかし、クラス変数(フィールド)を持つオブジェクトは機能しません。ここで私は常に「オブジェクトはターゲットタイプに同意しません」という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

は、なぜあなたはGetFieldの(Field.Name)) 'item.GetTypeを(呼び出している'だけでなく '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

私の知る限り、これはプロパティには機能しないはずです。文字列データのみを提供するのに対して、すべてのプロパティに文字列型があるわけではありません。とにかくあなたのfields-loopになぜネストされたループがありますか?あなたはすべてのフィールドのプロパティをループしているタイプ、私はかなり推測している。したがって、フィールドに文字列がある場合は、内部ループ内ですべてのフィールドを反復処理します(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はい、文字列のあるプロパティだけでなく、これに対して私は解決策を持っています。 –

関連する問題