[英]FieldInfo update subfield of field
美好的一天,
我需要創建將在存儲變量名和變量的新值的Dictionary上迭代的函數。 之后,我需要用該值更新類變量。
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"}});
總結一下,我需要創建一個函數來獲取存儲在另一個類中的類。 函數將通過字典迭代並更新類甚至是子字段的字段。
我建議為你的方法添加一個遞歸調用來設置屬性。 我已經改變了你的方法,因為我沒有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
方法的第三個參數不是很好,我會避免它,但我不知道如何使用泛型來解決它,在使用Activator
創建后,您將object
作為Type,並且對象沒有字段age
您正在使用Dictionary<string, string>
作為允許您僅設置字符串字段的參數,因此您必須假設您沒有任何其他字符串字段。 實際上,即使您將使用我建議做的Dictionary<string, object>
,這也會有效。
首先,如果要在此處將類作為參數傳遞Dictionary<string, object>
則需要將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;
}
}
}
}
}
在最后調用你的函數我創建了一個Dictionary<string,object>
實例,將它作為參數發送給函數
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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.