2016-12-23 3 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; 
} 

のようなクラスを持っていると私はこの方法は、それがうまくいく機能を使用したい場合。

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

「サブフィールド」(フィールド内のフィールド)

class test 
{ 
    public string age; 
} 

class test2 
{ 
    public test data; 
} 

を私はこのようなクラスを持っていると私は更新したい場合、問題は、私は、構文は次のようなものかもしれないことを考えていたが、私が持っていますどうすればいいのか分かりません。

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メソッドの3番目のパラメータは実際には素敵ではありませんが、私はそれを避けるでしょうが、で作成した後、ジェネリックで解決する方法はわかりませんあなたがタイプとしてobjectを取得し、オブジェクトは、あなたが他のを持っていないことを前提としなければならないので、あなたは、あなただけの文字列フィールドを設定することを可能にするパラメータとしてDictionary<string, string>を使用しているフィールドage

を持っていません。実際には、私がお勧めするDictionary<string, object>を使用する場合でも、これは動作します。

+0

絶対に巨大な感謝:)すべての作品を、それを送信するためにDictionary<string,object>インスタンスを作成した関数を呼び出し、私は詳細をカスタマイズします – Mrgnito

0

最初に、Dictionary変数を Dictionary<string, object>に変更する必要があります。この場合、ここでパラメータとしてクラスを渡す必要があります。 2つ目は、動作させる方法の例です。

class test 
{ 
    public string age; 
} 

class test2 
{ 
    public test data; 
} 

反射してフィールドを取得し、それに応じてtest2のインスタンスを更新するために、私はtestクラスのインスタンスを作成し、辞書にこれを追加したとします。最後に

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); 
関連する問題