2017-04-27 2 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

작동하지 않는 이유입니다.
해당 필드의 인스턴스 (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의 속성 값을 직접 설정할 수 있습니다.

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

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 예, 문자열의 속성이있는 것은 아니지만 이에 대한 해결책이 있습니다. –

관련 문제