C#如何使用delegate与GetGetMethod创建属性getter委托
实现decimal属性getter委托的方案
核心说明
getter方法存在返回值,无法使用无返回值的Action委托创建,需要使用带返回值的Func<TSource, TValue>泛型委托:第一个泛型参数为属性所属类的类型,第二个泛型参数为属性的返回值类型,通过PropertyInfo.GetGetMethod()拿到属性的get访问器后,传入Delegate.CreateDelegate即可生成可用的getter委托。
另外你原有代码中属性类型的判断逻辑写反了,IsAssignableFrom的调用规则为父类型.IsAssignableFrom(子类型),原写法无法正确筛选出decimal类型属性,建议直接通过类型相等判断筛选,逻辑更直观。
完整可运行代码
PerformanceCumulativePeriodEnd myObject = new PerformanceCumulativePeriodEnd(); myObject.Cumulative10Y = 2344; foreach (var propertyInfo in typeof(PerformanceCumulativePeriodEnd).GetProperties()) { // 筛选decimal/可空decimal类型属性 if (propertyInfo.PropertyType == typeof(decimal) || propertyInfo.PropertyType == typeof(decimal?)) { // 原有setter委托逻辑 var setter = (Action<PerformanceCumulativePeriodEnd, decimal?>)Delegate.CreateDelegate( typeof(Action<PerformanceCumulativePeriodEnd, decimal?>), propertyInfo.GetSetMethod()); setter.Invoke(myObject, 111); // 创建getter委托 var getter = (Func<PerformanceCumulativePeriodEnd, decimal?>)Delegate.CreateDelegate( typeof(Func<PerformanceCumulativePeriodEnd, decimal?>), propertyInfo.GetGetMethod()); // 调用getter读取属性值 decimal? propertyValue = getter.Invoke(myObject); // 此处即可拿到set后的值111 } }
补充说明
- 如果你的类中所有decimal属性都是非空值类型,委托泛型参数可以直接使用
decimal替代decimal?,能减少装箱拆箱开销,执行效率更高。 - 如果属性的get/set访问器是非公开的,需要给
GetGetMethod/GetSetMethod传入BindingFlags参数指定绑定规则,才能拿到对应的访问器方法。
内容的提问来源于stack exchange,提问作者daxu
相关产品推荐
相关产品推荐

