Trying to create two dictionaries of emitted delegates to allow for improved performance when dynamically getting/setting the values of properties.
Code:
Properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance)
.Where(p => p.CanRead && !p.GetIndexParameters().Any())
.AsEnumerable();
PropertyGetters = Properties.ToDictionary(p => p.Name, p => (Func<object, object>)Delegate.CreateDelegate(typeof(Func<object, object>), p.GetGetMethod()));
PropertySetters = Properties.Where(p => p.GetSetMethod() != null)
.ToDictionary(p => p.Name, p => (Action<object, object>)Delegate.CreateDelegate(typeof(Action<object, object>), p.GetSetMethod()));
However I get the following exception:
Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.
From what I have read this will be caused by static/indexed/value type properties, the Properties
collection contains no static or indexed properties but I do however need this to work for value type properties such as int
and double
.
How can I create the getters/setters that I need while keeping my code abstract and avoiding generics?
I was getting same error. I used Expressions API to fix this issue.
Note : Method to be referenced is
Delegate name is Formula and its signature is as follows
Get MethodInfo which is to be referenced as Delegate
Prepare arguments of the Delegate as Parameter Expression. Argument 1 :
Dictionary<string, float>
Argument 2 :List<Dictionary<string, float>>
var arg2Expression = Expression.Parameter(typeof(List>));
Generate final method Call Expression and return Delegate.
Ok ended up finding my answer from this question: MethodInfo.Invoke performance issue
More specifically this article: Making reflection fly and exploring delegates
Here is the jist of the code that I ended up with:
The generated delegates on average seem to be 80% faster than using reflection, so I am happy with the result!