I have class Settings
public class Settings
{
public string A{get;set;}
public bool B {get;set;}
public int C {get;set;}
}
I another class I have property type of Settings
public class VM
{
public class Settings Settings{get;set;}
}
I want setup values of property Settings with reflection.
I need pass argument type of object to InitializeSettings method.
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;
}
}
This sample code finish with exception
base = {"Object does not match target type."}
I don't know how can I set values on viewModel.Settings properties in Init method?
You don't need to do it that complicated. Once you have extracted the settings object, you can just update that:
PropertyInfo settingsProperty = viewModel.GetType().GetProperty("Settings");
Settings settings = (Settings) settingsProperty.GetValue(viewModel);
settings.A = "Foo";
settings.B = true;
settings.C = 123;
This is already enough to change the settings stored in the view model. If Settings
is a value type, you will have to write the changed settings object back to the object, like this:
settingsProperty.SetValue(viewModel, settings);
But that's really all you will have to do. Of course, if you know that viewModel
is of type VM
, you can just type-cast it, and access the property directly:
Settings settings = ((VM)viewModel).Settings;
So instead of using reflection, a much better way would be to define some base type, or an interface, that has the Settings
property and make your view models implement that:
public interface HasSettings
{
Settings Settings { get; set; }
}
public class VM : HasSettings
{ … }
That way, your method can accept a HasSettings
object instead of a plain object
, and you can just access the settings object directly:
public void Init (HasSettings viewModel)
{
viewModel.Settings.A = "Foo bar";
}
If you have different Settings
types with different properties, and you want to run reflection on those too, then you can do that as well:
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);
}
Again, no need to write the settings object back unless it's a value type.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.