美好的一天,
我需要创建将在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"}});
问题是,如果我有这样的课程,我想更新&#34; subfield&#34; (现场实地)
class test
{
public string age;
}
class test2
{
public test data;
}
我认为语法可能是这样的,但我不知道我怎么能这样做。
UpdateValues(typeof(test2), new Dictionary<string, string>{{"data.age", "17"}});
总结一下,我需要创建一个函数来获取存储在另一个类中的类。函数将通过字典迭代并更新类甚至是子字段的字段。
答案 0 :(得分: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
方法的第三个参数不是很好,我会避免它,但我不知道如何使用泛型来解决它,在用Activator
创建后你得到{{ 1}}作为类型,对象没有字段object
您使用age
作为参数,只允许您设置字符串字段,因此您必须假设您没有任何其他字符串字段。实际上,即使您使用Dictionary<string, string>
,我也建议这样做。
答案 1 :(得分: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;
}
}
}
}
}
在最后调用你的函数我创建了一个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);