Задача написать универсальный фильтр для коллекции Card по различным CardValue.
class Card
{
public CardValue this[string key]
{
get { return this.GetCardValue(key); }
}
}
Как показано выше, он содержит коллекцию классов CardValue
class CardValue
{
public string Key {get; private set;}
public string Title {get; set;}
public string Content {get; set;}
}
Пытаюсь решить эту задачу используя лямбда-выражения. Хочется получить решение вида:
// ...
var prediacte = PredicateBuilder.False(Card)(); // http://www.albahari.com/nutshell/predicatebuilder.aspx
foreach(FilterRule rule in rules)
{
predicate = predicate.Or(Card.GetFilter(rule.Key, rule.Condition, rule.Value));
}
var items = from card in cards.AsQuerable().Where(prediacte) select card;
// ...
Проблема в том, как сравнивать значения индексированного свойства класса Card используя слудующую функцию:
public static Expression<Func<Card, bool>> GetFilter(string filterKey, string filterCondition, string filterValue)
{
// Массив условий сравнения
var conditions= new Dictionary(string, Func<Expression, Expression, Expression>>()
{
{ "==", (x, y) => Expression.Equal(x, y) },
{ ">", (x, y) => Expression.GreaterThan(x, y) }
// ...
}
// Доступ к элементу Card[Key]
var objExpr = Expression.Parameter(typeof(Card), "Card");
var keyExpr = Expression.Parameter(typeod(string), "Key");
var valueExpr = Expression.Parameter(typeod(CardValue), "Value");
var indexExpr = Expression.Property(objExpr, "Item", keyExpr); // Выражение доступа к элементу
// **** var X = ??? ****
// Значение фильтра
var testValue = Expression.Constant(filterValue);
// Итоговое выражение. **** сюда подставить выражение X ****
return Expression.Lambda<Func<Card, bool>>(conditions[filterCondition](X, testValue), objExpr);
}
Как написать выражение X, чтобы оно предоставляло доступ к полю Card[filterKey].Content?
p.s. Альтернативный вариант, как мне кажется, когда нужен доступ только до Card[filterKey], а метод Equal перегружен в классе CardValue.
loading.............. 87%