【发布时间】:2019-06-06 12:45:36
【问题描述】:
我正在研究一种缓存解决方案,以获取类的所有属性字段,从中创建 getter 和 setter 委托并存储它们。
这就是我目前的做法:
// entity is a class with a single public property called 'Name'
var entity = new Entity("Cat");
var nameProp = typeof(Entity)
.GetProperties()
.Single(x => x.Name == nameof(Entity.Name));
// getting getter and setter methods
var namePropGetter = nameProp.GetGetMethod();
var namePropSetter = nameProp.GetSetMethod();
// creating delegates for getter and setter methods
var namePropGetterDelegate = (Func<Entity, string>)Delegate.CreateDelegate(typeof(Func<Entity, string>), namePropGetter);
var namePropSetterDelegate = (Action<Entity, string>)Delegate.CreateDelegate(typeof(Action<Entity, string>), namePropSetter);
所有 getter 都存储在一个 Dictionary 中,所有 setter 都存储在另一个 Dictionary 中。这可以让我快速获取或设置对象的值,而不是使用传统的 PropertyField.GetValue() 或 PropertyField.SetValue()。
唯一的问题是 getter 和 setter 委托的存储。
我尝试将所有 getter 存储到 Func<TargetClass, object> 并将 setter 存储到 Action<TargetClass, object> 中,如下所示:
var getterDelegate = (Func<Entity, object>)Delegate.CreateDelegate(typeof(Func<Entity, object>), namePropGetter);
var setterDelegate = (Action<Entity, object>)Delegate.CreateDelegate(typeof(Action<Entity, object>), namePropSetter);
但它会给我以下错误:
无法绑定到目标方法,因为它的签名或安全透明度与委托类型的不兼容。
将所有内容存储在Delegate 中会迫使我使用DynamicInvoke(),这违背了首先缓存所有内容的目的,因为它很慢。
【问题讨论】:
-
你到底想做什么?
-
你需要告诉编译器如何转换。例如。
var setterDelegate = (Action<Entity, string>)Delegate.CreateDelegate(typeof(Action<Entity, string>), namePropSetter); var objectSetterDelegate = (o, x) => getterDelegate(o, (string)x) -
也许你真正需要的只是
Func<Entity, object> namePropGetter = (entity) => namePropGetter.GetValue(entity);这只有在你不关心返回类型并且你希望所有的属性值都转换为object时才有意义。否则将它们全部放在Dictionary中不会有太大的作用。您将拥有一组都返回不同类型的函数,并且很难用它来做任何有用的事情。
标签: c# delegates system.reflection