Given the name of the property, how can I create a delegate to get its value

We have code that sets the name of the property, uses reflection to implement Comparer.

I would like to keep the delegate / Func to get the value, and not pay the reflection price every time we need to get the value.

For a class like this:

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

I tried to write a function that would create a delegate for me

Func<T, object> CreateGetFuncFor<T>(string propertyName)
{
    PropertyInfo prop = typeof(T).GetProperty(propertyName);

    return (Func<T, object>)Delegate.CreateDelegate(typeof(Func<T, object>), 
                                                    null, 
                                                    prop.GetGetMethod());
}

The following code is great for getting a name

var person = new Person { Name = "Dave", Age = 42 };

var funcitonToGetName = CreateGetFuncFor<Person>("Name");
Console.WriteLine(funcitonToGetName(person));

var functionToGetAge = CreateGetFuncFor<Person>("Age");

but for Age proerty it throws an ArgumentException with the message "Target method binding failed"

What am I missing? Is there any other way to do this?

+5
source share
2 answers

, , . ...

object, Func<T,object>. ( , .)

Func<T, object> CreateGetFuncFor<T>(string propertyName)
{
    var parameter = Expression.Parameter(typeof(T), "obj");
    var property = Expression.Property(parameter, propertyName);
    var convert = Expression.Convert(property, typeof(object));
    var lambda = Expression.Lambda(typeof(Func<T, object>), convert, parameter);

    return (Func<T, object>)lambda.Compile();
}
+8

, , Age :

public int Age {get; private set;}

, int, , object, String is.

:

Func<T, R> CreateGetFuncFor<T, R>(string propertyName)
{
    PropertyInfo prop = typeof(T).GetProperty(propertyName);
    return (Func<T, R>)Delegate.CreateDelegate(typeof(Func<T, R>), 
                                                    null, 
                                                    prop.GetGetMethod());
}

var functionToGetAge = CreateGetFuncFor<Person, int>("Age");
+1

All Articles