I am trying to undersand how to use delegate and GetGetMethod/GetSetMethod to get and set property. Say I have a class PerformanceCumulativePeriodEnd and I am only interested in getting and setting the decimal properties.
Setter is easy to do, but how do I create a getter delegation?
PerformanceCumulativePeriodEnd myObject = new PerformanceCumulativePeriodEnd();
myObject.Cumulative10Y = 2344;
foreach (var propertyInfo in typeof(PerformanceCumulativePeriodEnd).GetProperties())
{
if (propertyInfo.PropertyType.IsAssignableFrom(typeof(decimal)))
{
var setter = (Action<PerformanceCumulativePeriodEnd, decimal?
>)Delegate.CreateDelegate(
typeof(Action<PerformanceCumulativePeriodEnd, decimal?>),
propertyInfo.GetSetMethod());
setter.Invoke(myObject, 111);
var getter =??? //How do I create a Action for Getter?
}
}
CodePudding user response:
The immediate equivalent would be:
var myObject = new PerformanceCumulativePeriodEnd();
myObject.Cumulative10Y = 2344;
foreach (var propertyInfo in typeof(PerformanceCumulativePeriodEnd).GetProperties())
{
if (propertyInfo.PropertyType == typeof(decimal?))
{
var setter = (Action<PerformanceCumulativePeriodEnd, decimal?
>)Delegate.CreateDelegate(
typeof(Action<PerformanceCumulativePeriodEnd, decimal?>),
propertyInfo.GetSetMethod());
setter(myObject, 111);
var getter = (Func<PerformanceCumulativePeriodEnd, decimal?
>)Delegate.CreateDelegate(
typeof(Func<PerformanceCumulativePeriodEnd, decimal?>),
propertyInfo.GetGetMethod());
var val = getter(myObject);
}
}
I changed the criterion to == typeof(decimal?)
to include only properties whose exact type is nullable decimal.
Bonus: Here is another version:
var myObject = new PerformanceCumulativePeriodEnd();
myObject.Cumulative10Y = 2344;
foreach (var propertyInfo in typeof(PerformanceCumulativePeriodEnd).GetProperties())
{
if (propertyInfo.PropertyType == typeof(decimal?))
{
Action<PerformanceCumulativePeriodEnd, decimal?> setter =
(obj, v) => propertyInfo.GetSetMethod().Invoke(obj, new object[] { v });
setter(myObject, 111);
Func<PerformanceCumulativePeriodEnd, decimal?> getter =
obj => (decimal?)propertyInfo.GetGetMethod().Invoke(obj, null);
var val = getter(myObject);
}
}
In case you do not really need them as delegates:
var myObject = new PerformanceCumulativePeriodEnd();
myObject.Cumulative10Y = 2344;
foreach (var propertyInfo in typeof(PerformanceCumulativePeriodEnd).GetProperties())
{
if (propertyInfo.PropertyType == typeof(decimal?))
{
// set
propertyInfo.GetSetMethod().Invoke(myObject, new object[] { 111m });
// get
var val = (decimal?)propertyInfo.GetGetMethod().Invoke(myObject, null);
}
}
CodePudding user response:
You could try to define your delegate which returns a decimal and use the GetMethod
property to create your delegate.
Something like:
public delegate Result ActionResult<in T, Result>(T obj);
and then in your main function:
var getter = (ActionResult<PerformanceCumulativePeriodEnd, decimal?>)Delegate.CreateDelegate(
typeof(ActionResult<PerformanceCumulativePeriodEnd, decimal?>), propertyInfo.GetMethod);
var i = getter.Invoke(myObject);