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 share
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 to share
The answer is actually the same as this other SO question / answer on INotifyPropertyChanged by Phil .
+1
user111013
source
to share