[英]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.