Udontknow Udontknow - 1 year ago 78
C# Question

Creating functions to retrieve values of properties retrieved via reflection

Im writing code to transfer data of my ORM entities into a dataset. Because i dont want to write special code for each type defining which properties need to be written down, i am currently using reflection (calling GetProperties on the type of the entities, building up a DataTable for this type and then calling GetValue on each Propertyinfo for each entity). Status quo: It works, but it is slow.

Now i´m trying to build up a method that is returning a function to retrieve the value of certain properties fast, but i am having a hard time here. This is what i got so far:

/// <summary>
/// creates a func that will return the value of the given property
/// </summary>
/// <typeparam name="T">type of the entity</typeparam>
/// <param name="propertyInfo">the property to get the value from</param>
/// <returns>a function accepting an instance of T and returning the value of the property</returns>
private Func<T, object> CreateGetPropertyFunc<T>(PropertyInfo propertyInfo)
MethodInfo getMethod = propertyInfo.GetGetMethod();
return (Func<T, object>)Delegate.CreateDelegate(typeof(Func<T, object>), getMethod);

These are my unit tests:

public void TestGenerateDelegate()
var employee = new Employee
Id = 1,
Name = "TestEmployee",

Func<Employee, object> getIdValueFunc = CreateGetPropertyFunc<Employee>(typeof(Employee).GetProperty("Id"));
Assert.AreEqual(1, getIdValueFunc(employee));

public void TestGenerateDelegateName()
var employee = new Employee
Name = "Test"

Func<Employee, object> getNameValueFunc = CreateGetPropertyFunc<Employee>(typeof(Employee).GetProperty("Name"));
Assert.AreEqual("Test", getNameValueFunc(employee));

When i call the first one, an ArgumentException with the message "Exception while binding to the target method" (translated, may be different text) is thrown . The second test passes instead.

I´m pretty sure i´m not correctly handling that CreateDelegate method. Could anyone point me to the right direction, please?


As PetSerAI statet, it seems to be a problem with the variance, values primitive types cannot be returned as object via CreateDelegate...

Answer Source

You can use expression trees to dynamically create delegate, which reference specified property:

private Func<T, object> CreateGetPropertyFunc<T>(PropertyInfo propertyInfo) {
    ParameterExpression p = Expression.Parameter(typeof(T));
    return Expression.Lambda<Func<T, object>>(
        Expression.Convert(Expression.Property(p, propertyInfo), typeof(object)),
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download