0

我有一个对象实例。在对象的构造函数中,我想允许用户传入一个字典来初始化对象的一些(如果不是全部)属性。现在,我想做的不是使用条件,而是使用反射,反映对象实例中包含的属性,如果属性名称映射到字典中的键,则使用相应的值更新属性值在字典中。

在处理这个问题时,我有以下代码,但它不会更新我的对象实例的值。希望能得到一些帮助以使其正常工作吗?

 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);
                    }
                }

            }
        }
4

2 回答 2

4

首先,您是否附加了一个调试器来检查您是否进入了最嵌套的内部if?如果你没有进入最嵌套的内部if,你能通过比较你期望发生的事情和你在调试器中检查时实际发生的事情来找出原因吗?

其次,在最嵌套的if中,您可以删除前两行,并在第三行替换propertypropertyInfo(当您删除前两行时,这将是唯一剩下的行)。您已经有了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
    }
}

请注意,这正是您的逻辑并且有效。这有帮助吗?

于 2013-06-21T21:42:29.227 回答
-1

如果您将其切换并执行,它会更好吗?

    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");
                }
            }
        }
    }
于 2013-06-21T21:33:01.893 回答