Use reflection to assign the value of the Func <Product, object> property

If I have a Product class:

public class Product
{
    public string Title { get; set; }
    public string Make { get; set; }
    public Decimal Price { get; set; } //(Edit) - Added non-string
}

      

And I have a property in another class, declared as:

Func<Product, object> SortBy { get; set; }

      

I can install SortBy using:

SortBy = p => p.Title;

      

But how would I, using reflection, make the same assignment if I had the SortBy property name stored as a string, eg.

string sortField = "Title";

SortBy = /*Some reflection using sortField*/;

      

+3


source to share


3 answers


You need to use expression trees to create a new method at runtime:

var p = Expression.Parameter(typeof(Product));
SortBy = Expression.Lambda<Func<Product, object>>(
    Expression.Property(p, sortField),
    p
).Compile();

      



To work with type values, you need to insert text:

var p = Expression.Parameter(typeof(Product));
SortBy = Expression.Lambda<Func<Product, object>>( 
    Expression.TypeAs(Expression.Property(p, sortField), typeof(object)), 
    p
).Compile();

      

+5


source


To make it work for decimal and other value types, you can use generics:

static void SetSortBy<T>(string sortField) {
    var m = typeof(Product).GetProperty(sortField).GetGetMethod();
    var d = Delegate.CreateDelegate(typeof(Func<Product, T>), m) 
            as Func<Product, T>;
    SortBy = product => d(product);
}

      



...

SetSortBy<decimal>("Price");
SetSortBy<object>("Title"); // or <string>

      

+2


source


The answer is actually the same as this other SO question / answer on INotifyPropertyChanged by Phil .

+1


source







All Articles