Expanding upon the answer given by @zwcloud, we can use any property type if you are using a version of .NET that supports the dynamic
type.
Then if you need to dynamically load settings into a property you only have the string name of, you need a separate setter dictionary.
Now we arrive at a solution where we can get or set any property by name. It does take a lot of ceremony to get here but it ends up being much better than reflection.
To make an extension out of this we would need to get into code weaving, where this code could be generated for you at compile time. Tune in next time for another exciting episode of "ain't nobody got time for that".
public class Car
{
public string MakeA { get; set; }
public int MakeB { get; set; }
public decimal MakeC { get; set; }
private readonly Dictionary<string, Func<dynamic>> _propertyGetterMap;
private readonly Dictionary<string, Action<dynamic>> _propertySetterMap;
public Car()
{
_propertyGetterMap= new Dictionary<string, Func<dynamic>>(3)
{
{ nameof(MakeA), () => MakeA },
{ nameof(MakeB), () => MakeB },
{ nameof(MakeC), () => MakeC }
};
_propertySetterMap= new Dictionary<string, Func<dynamic>>(3)
{
{ nameof(MakeA), (value) => MakeA = value.ToString() },
{ nameof(MakeB), (value) => MakeB = (int)Convert.ChangeType(value, typeof(int)) },
{ nameof(MakeC), (value) => MakeC = (decimal)Convert.ChangeType(value, typeof(decimal)) }
};
}
public string GetPropertyValue(string propertyName)
{
if (_stringPropertyMap.TryGetValue(propertyName, out var getter))
{
return getter();
}
throw new InvalidOperationException($"{nameof(Car)} doesn't have a property of name {propertyName}");
}
public string SetPropertyValue(string propertyName, dynamic value)
{
if (_stringPropertyMap.TryGetValue(propertyName, out var setter))
{
setter(value);
}
throw new InvalidOperationException($"{nameof(Car)} doesn't have a property of name {propertyName}");
}
}