我有课程设置
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属性的值?
答案 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);
}
同样,除非它是值类型,否则无需再写回设置对象。