Используйте отражение, чтобы назначить значение Funcимущество - PullRequest
3 голосов
/ 18 марта 2012

Если у меня есть класс Продукт:

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 используя:

SortBy = p => p.Title;

Но как бы я, используя отражение, сделал такое же назначение, если бы у меня было имя свойства для SortBy, хранящееся в виде строки, например

string sortField = "Title";

SortBy = /*Some reflection using sortField*/;

Ответы [ 3 ]

5 голосов
/ 18 марта 2012

Вам необходимо использовать деревья выражений , чтобы создать новый метод во время выполнения:

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();
2 голосов
/ 18 марта 2012

Чтобы заставить его работать с десятичными и другими типами значений, вы можете использовать обобщенные значения:

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>
1 голос
/ 18 марта 2012

Ответ фактически совпадает с этим другим ТАК вопрос / ответ на INotifyPropertyChanged Phil .

...