principlecsharpMinor
Best practice instantiating generic delegates and accessing property getters
Viewed 0 times
genericinstantiatingpracticegetterspropertydelegatesandaccessingbest
Problem
I want to create delegates to access properties of different objects without knowing them in advance.
I have the following definitions
where T can be decimal, string, datetime or int
I have some initializing code that will create MyMethod delegates, based on the reflected properties of my object as follows:
Is there a better way to
However, performance is an issue, since these delegates will be called frequently (ticking scenario), so any casting will slow it down. While a more elegant solution is desirable, performance is still my main concern
I have the following definitions
public delegate T MyMethod(K data);
public static MyMethod CreatePropertyGetter(PropertyInfo property)
{
MethodInfo mi = property.DeclaringType.GetMethod("get_" + property.Name);
return (MyMethod)Delegate.CreateDelegate(typeof(MyMethod), mi);
}where T can be decimal, string, datetime or int
I have some initializing code that will create MyMethod delegates, based on the reflected properties of my object as follows:
foreach (PropertyInfo property in entityType.GetProperties())
{
switch (property.PropertyType.Name)
{
case "System.Decimal":
return CreatePropertyGetter(property);
case "System.DateTime":
return CreatePropertyGetter(property);
case "System.String":
return CreatePropertyGetter(property);
}
}Is there a better way to
- create property getters?
- enumerate through the supported property types hard-coded as strings?
However, performance is an issue, since these delegates will be called frequently (ticking scenario), so any casting will slow it down. While a more elegant solution is desirable, performance is still my main concern
Solution
As my answer on Stack Overflow states, there is a solution which allows you to create a getter delegate for any type, so the entire switch block can be dropped. Personally, I find that the cleanest solution. The only overhead of this approach is the cast from object to the specific type where necessary. (For a getter this would happen only once on the return value.) I'm guessing if you would benchmark this, the result would be negligible.
When you are certain that the only types required are those specified, or that no new types are expected very often, you could still opt to use your current approach. I would apply a few changes however:
The last point is possible as follows:
Ofcourse you still have to cast from object to the desired type.
UPDATE:
As Timwi pointed out in the comments,
When you are certain that the only types required are those specified, or that no new types are expected very often, you could still opt to use your current approach. I would apply a few changes however:
- Use PropertyInfo.GetGetMethod() to retrieve your MethodInfo for the getter.
- Use the type of PropertyType directly to determine which CreatePropertyGetter to call instead of the name of the type.
- Use
Funcinstead ofMyMethod.
- Use a Dictionary holding anonymous functions which create the correct delegate for the specified type of the key. This can replace the switch statement.
The last point is possible as follows:
Dictionary> getterCreators =
new Dictionary>
{
{ typeof(string), p => CreatePropertyGetter(p) },
{ typeof(DateTime), p => CreatePropertyGetter(p) },
{ typeof(decimal), p => CreatePropertyGetter(p) }
};Ofcourse you still have to cast from object to the desired type.
UPDATE:
As Timwi pointed out in the comments,
p => CreatePropertyGetter(p) can be further reduced to: CreatePropertyGetter.Code Snippets
Dictionary<Type, Func<PropertyInfo, object>> getterCreators =
new Dictionary<Type, Func<PropertyInfo, object>>
{
{ typeof(string), p => CreatePropertyGetter<T, string>(p) },
{ typeof(DateTime), p => CreatePropertyGetter<T, DateTime>(p) },
{ typeof(decimal), p => CreatePropertyGetter<T, decimal>(p) }
};Context
StackExchange Code Review Q#1188, answer score: 7
Revisions (0)
No revisions yet.