【问题标题】:Set property value with reflection使用反射设置属性值
【发布时间】:2014-03-08 19:35:49
【问题描述】:

我有班级设置

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 属性的值?

【问题讨论】:

  • 您能否为您使用反射的原因添加一些背景信息?
  • 你也永远不会实例化你的类。我感觉你把事情复杂化了一点。您究竟想用这段代码完成什么?
  • 我有几个模块,每个模块都是类库。每个模块都有自己的 app.config 和自己的 Setting 类定义(具有不同的属性)。每个模块中也可以有几个 ViewModel。我想在服务模块中有一个服务类,它将为他们的 app.config 中的模块设置设置。

标签: c# reflection properties


【解决方案1】:

您不需要那么复杂。提取设置对象后,您可以对其进行更新:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-18
    • 1970-01-01
    • 2010-10-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多