我有一个Object实例。在对象的构造函数中,我希望允许用户传入一个Dictionary,用它来初始化对象的一些(如果不是全部)属性。现在,我想做的不是使用条件,而是使用反射,反射对象实例中包含的属性,如果属性名称映射到字典中的一个键,则使用字典中的相应值更新属性值。
在处理这个问题时,我有以下代码,但它不更新我的对象实例的值。我希望你能帮我解决这个问题? public void Initialize()
{
if (Report.GlobalParameters != null)
{
PropertyInfo[] propertyInfos = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo propertyInfo in propertyInfos)
{
if (Report.GlobalParameters.ContainsKey(propertyInfo.Name))
{
Type type = this.GetType();
PropertyInfo property = type.GetProperty(propertyInfo.Name);
property.SetValue(this, Report.GlobalParameters[propertyInfo.Name], null);
}
}
}
}
首先,您是否附加了一个调试器来检查您是否正在进入最嵌套的if
?如果你没有进入最嵌套的if
,你能通过比较你期望发生的事情和你在调试器中检查时实际发生的事情来找出原因吗?
第二,在最嵌套的if
中,您可以删除前两行,并在第三行中用propertyInfo
替换property
(当您删除前两行时,这将是唯一剩下的行)。你已经有了名字的PropertyInfo
,为什么还要再查一遍?
这里有一个小的工作的例子,你有什么应该帮助你:
using System;
using System.Collections.Generic;
class Foo {
public int Bar { get; set; }
public Foo(Dictionary<string, object> values) {
var propertyInfo = this.GetType().GetProperties();
foreach(var property in propertyInfo) {
if(values.ContainsKey(property.Name)) {
property.SetValue(this, values[property.Name], null);
}
}
}
}
class Program {
public static void Main(String[] args) {
Dictionary<string, object> values = new Dictionary<string, object>();
values.Add("Bar", 42);
Foo foo = new Foo(values);
Console.WriteLine(foo.Bar); // expect 42
}
}
注意,这正是你的逻辑,它工作。这有帮助吗?
如果你把它转换成这样,效果会更好吗?
public void Initialize()
{
if (Report.GlobalParameters != null)
{
foreach (KeyValuePair<string, object> kvp in Report.GlobalParameters)
{
PropertyInfo pi = this.GetType().GetProperty(kvp.Key, BindingFlags.Public | BindingFlags.Instance);
if (pi != null)
{
try
{
pi.SetValue(this, kvp.Value, null);
}
catch (Exception ex)
{
MessageBox.Show(kvp.Key + Environment.NewLine + ex.ToString(), "Error Setting Property Value");
}
}
else
{
MessageBox.Show(kvp.Key, "Property Not Found");
}
}
}
}