使用反射设置属性值

时间:2014-03-08 19:35:50

标签: c# reflection properties

我有课程设置

public class Settings
{
  public string A{get;set;}
  public bool B {get;set;}
  public int C {get;set;}
}

我是另一个类,我有属性类型的设置

public class VM
{
   public class Settings Settings{get;set;}
}

我想要使用反射设置属性设置值。

我需要将对象的参数类型传递给InitializeSettings方法。

 public void Init(object viewModel)
    {
        try
        {
            PropertyInfo settings = viewModel.GetType().GetProperty("Settings");

            PropertyInfo[] settingsProperties = settings.PropertyType.GetProperties();

            foreach (PropertyInfo settingsProperty in settingsProperties)
            {
                object value = //load from app.config

                var convertedValue = Convert.ChangeType(value, settingsProperty.PropertyType);

                //how set  value ???
                settingsProperty.SetValue(settings, convertedValue, null);

            }
        }
        catch (Exception exception)
        {
            throw;
        }
    }

此示例代码完成,但带有异常

base = {"Object does not match target type."}

我不知道如何在Init方法中设置viewModel.Settings属性的值?

1 个答案:

答案 0 :(得分:2)

你不需要那么复杂。解压缩设置对象后,您只需更新:

PropertyInfo settingsProperty = viewModel.GetType().GetProperty("Settings");
Settings settings = (Settings) settingsProperty.GetValue(viewModel);

settings.A = "Foo";
settings.B = true;
settings.C = 123;

这已足以更改存储在视图模型中的设置。如果Settings是值类型,则必须将更改的设置对象写回对象,如下所示:

settingsProperty.SetValue(viewModel, settings);

但这真的是你所要做的。当然,如果你知道viewModel的类型为VM,你可以输入它,然后直接访问该属性:

Settings settings = ((VM)viewModel).Settings;

因此,不是使用反射,更好的方法是定义一些具有Settings属性的基类型或接口,并使您的视图模型实现:

public interface HasSettings
{
    Settings Settings { get; set; }
}

public class VM : HasSettings
{ … }

这样,您的方法可以接受HasSettings对象而不是普通object,您只需直接访问设置对象:

public void Init (HasSettings viewModel)
{
    viewModel.Settings.A = "Foo bar";
}

如果你有不同的Settings类型具有不同的属性,并且你想对它们进行反射,那么你也可以这样做:

PropertyInfo settingsProperty = viewModel.GetType().GetProperty("Settings");
object settings = settingsProperty.GetValue(viewModel);

for (PropertyInfo prop in settings.GetType().GetProperties())
{
    object value = GetValueForPropertyName(prop.Name); // magic
    prop.SetValue(settings, value);
}

同样,除非它是值类型,否则无需再写回设置对象。