2016-12-23 2 views
6

좋은 날,FieldInfo 필드의 서브 필드 업데이트

변수 이름과 변수의 새로운 값을 저장하는 사전을 반복 할 함수를 만들 필요가 있습니다. 그런 다음 클래스 변수를 해당 값으로 업데이트해야합니다.

void UpdateValues(Type type, Dictionary<string, string> values) 
{ 
    foreach (var value in values) 
    { 
     var fieldInfo = selected.GetComponent(type).GetType().GetField(value.Key); 
     if (fieldInfo == null) continue; 

     fieldInfo.SetValue(selected.GetComponent(type), value.Value); 
    } 
} 

효과가 있지만 조금 개선하고 싶지만 가능한지 절대 알지 못합니다. 알다시피,이 함수는 특정 클래스뿐만 아니라 모든 클래스를 허용 할 수 있습니다. 만약 내가

class test 
{ 
    public string age; 
} 

같은 클래스는 내가 기능이 방법을 사용, 그것은 작동합니다. 나는이 같은 클래스가 나는 "서브 필드"(필드 필드)

class test 
{ 
    public string age; 
} 

class test2 
{ 
    public test data; 
} 
내가 그 구문은이 같은 수 생각

를 업데이 트하려는 경우

UpdateValues(typeof(test), new Dictionary<string, string>{{"age", "17"}}); 

문제입니다,하지만 난이 내가 어떻게 그럴 수 있을지 모르겠다. 그것을 요약하면

UpdateValues(typeof(test2), new Dictionary<string, string>{{"data.age", "17"}}); 

, 나는 다른 클래스에 저장되어 수업을합니다 기능을 확인해야합니다. 함수는 사전을 통해 반복하여 클래스의 필드와 하위 필드까지 업데이트합니다.

답변

1

속성을 설정하기 위해 재귀 호출을 메서드에 추가 할 것을 제안합니다. 내가 selected 대상이 없기 때문에 내가 당신의 방법을 조금 변경, 그것은

void UpdateValues<T>(T obj, Dictionary<string, string> values) 
{ 
    foreach (var value in values) 
    {  
     SetProperty(obj, value.Key, value.Value); 
    } 
} 


public void SetProperty<T>(T obj, string valueKey, string value, Type type= null) 
{ 
    var typeToUse = type ?? typeof(T); 
    var pointIndex = valueKey.IndexOf("."); 
    if (pointIndex!=-1) 
    { 
     var subKey = valueKey.Substring(0, pointIndex); 
     var fieldInfo = typeToUse.GetField(subKey); 
     var propObj = fieldInfo.GetValue(obj) 
         ?? Activator.CreateInstance(fieldInfo.FieldType);   
     SetProperty(propObj, valueKey.Substring(pointIndex+1), value, fieldInfo.FieldType); 
     fieldInfo.SetValue(obj, propObj); 
    } 
    else 
    {  
     var fieldInfo = typeToUse.GetField(valueKey);  
     if (fieldInfo != null) 
      fieldInfo.SetValue(obj, value); 
    } 
} 

그것은 당신이

class test3 
{ 
    public test2 data; 
} 

를 정의하고 호출 할 경우에도 작동 매개 변수로 오브젝트를

UpdateValues(t, new Dictionary<string, string>{{"age", "17"}}); 
UpdateValues(t2, new Dictionary<string, string> { { "data.age", "17" } }); 
UpdateValues(t3, new Dictionary<string, string> { { "data.data.age", "17" } }); 

SetProperty 메서드의 세 번째 매개 변수는 실제로 좋지는 않습니다. 피할 수는 있지만,를 생성 한 후 제네릭으로 해결하는 방법을 모르겠습니다.당신은 유형으로 object을 얻고, 객체는 당신이 다른이없는 것으로 가정해야한다, 그래서 당신은, 당신은 단지 문자열 필드를 설정할 수있는 매개 변수로 Dictionary<string, string>을 사용하는 필드 age

이 없습니다. 비록 내가 할 것을 제안한다면 Dictionary<string, object>을 사용할지라도 실제로 이것은 작동 할 것입니다.

+0

절대적으로 큰 감사 : 모든 작품을 보낼 수있는 Dictionary<string,object> 인스턴스를 생성 한 함수를 호출, 나는 세부 사항을 사용자 정의합니다 – Mrgnito

0

먼저 매개 변수로 클래스를 전달하려면 먼저 Dictionary 변수를 Dictionary<string, object>으로 변경해야합니다. 두 번째 방법 다음은 작동시키는 방법의 예입니다.

class test 
{ 
    public string age; 
} 

class test2 
{ 
    public test data; 
} 

내가 test 클래스의 인스턴스를 생성 및 반사 필드를 얻고 그에 따라 test2의 인스턴스를 갱신하기 위해, 사전에 추가 있다고 가정 할 수 있습니다.결국

public void UpdateValues(object test2, Dictionary<string, object> dict) 
    { 
     var fieldValues = test2.GetType() 
        .GetFields() 
        .ToList(); 
     foreach (var value in dict) 
     { 
      foreach (var field in fieldValues) 
      { 


       if (value.Key == field.Name) 
       { 
        bool obj = field.FieldType == typeof(test); 
        if (obj) 
        { 
         if (dict.ContainsKey("data")) 
         { 
         var prop = test2.GetType().GetField("data", System.Reflection.BindingFlags.Public 
         | System.Reflection.BindingFlags.Instance); 
         prop.SetValue(test2, dict["data"]); 
         break; 
         } 
        } 
        else 
        { 
         var prop = test2.GetType().GetField(value.Key, System.Reflection.BindingFlags.Public 
         | System.Reflection.BindingFlags.Instance); 
         prop.SetValue(test2, value.Value); 
         break; 
        } 
       } 
      } 

     } 
    } 

당신은 내가 함수에 매개 변수로

object test2 = new test2(); 
test t = new test(); 
t.age = "10"; 
Dictionary<string, object> dict = new Dictionary<string, object>(); 
dict.Add("data", t); 
UpdateValues(test2, dict); 
관련 문제