使用反射为Func<;产品,对象>;所有物

本文关键字:产品 对象 所有物 gt lt 反射 Func | 更新日期: 2023-09-27 18:28:05

如果我有一个类产品:

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

我在另一个类中有一个属性声明为:

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

我可以使用设置排序方式

SortBy = p => p.Title;

但是,如果我将SortBy的属性名称存储为字符串(例如),我将如何使用反射进行相同的赋值

string sortField = "Title";
SortBy = /*Some reflection using sortField*/;

使用反射为Func<;产品,对象>;所有物

您需要使用表达式树在运行时创建一个新方法:

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

要使用值类型,您需要插入一个类型转换:

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

要使其与十进制和其他值类型一起工作,可以使用泛型:

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>

答案实际上与Phil.

在INotifyPropertyChanged上的其他SO问题/答案相同