isxaker
@isxaker

Как в рантайме изменять лямбда выражение?

У меня есть такой пример кода
public class Person
{
            public bool FirstNameIsActive { get; set; }
            public bool SecondNameIsActive { get; set; }
}

List<Person> persons = new List<Person>();

public IEnumerable<Person> filter(string prop, bool isActive)
{
            Func<Person, bool> predicate = null;
            if (prop == "FirstNameIsActive") 
                   predicate = x => x.FirstNameIsActive == isActive;
            else if (prop == "SecondNameIsActive") 
                   predicate = x => x.SecondNameIsActive == isActive;

            return persons.Where(predicate);
}


Как избежать дублирования кода в методе filter() ? То есть мне нужно что-то вроде
predicate = x => x.PROPERTY == isActive;
  • Вопрос задан
  • 3188 просмотров
Решения вопроса 1
isxaker
@isxaker Автор вопроса
//property selector
Func<Person, Boolean> propertySelector = person => person.FirstNameIsActive;

//your predicate
Func<Person, Boolean> predicate = person => propertySelector(person) == true;

//new person with true, false properties.
Person p = new Person() {FirstNameIsActive = true,SecondNameIsActive = false};

Console.WriteLine(predicate(p).ToString()); //prints true

//change the property selector
propertySelector = person => person.SecondNameIsActive;

//now the predicate uses the new property selector
Console.WriteLine(predicate(p).ToString()); //prints false
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@veitmen
Я бы посоветовал посмотреть на DynamicLinq.

Подробнее тут.
Ответ написан
Комментировать
isxaker
@isxaker Автор вопроса
public class Person
{
    public bool FirstNameIsActive { get; set; }
    public bool SecondNameIsActive { get; set; }
}

public List<Person> list = new List<Person>() { 
    new Person() { 
        FirstNameIsActive = true, 
        SecondNameIsActive = false 
    }, 
    new Person() { 
        FirstNameIsActive = false, 
        SecondNameIsActive = true 
    } 
};

private IQueryable<Person> Filter(PropertyInfo property, bool isActive)
{
    IQueryable<Person> queryableData = list.AsQueryable<Person>();
    //create input parameter
	ParameterExpression inputParam = Expression.Parameter(typeof(Person));
	//left contition
    Expression left = Expression.Property(inputParam, property);
    //right condition
    Expression right = Expression.Constant(isActive, typeof(bool));
    //equals
    Expression e1 = Expression.Equal(left, right);
    //create call
    MethodCallExpression whereCallExpression = Expression.Call(
                                                            typeof(Queryable),
                                                            "Where",
                                                            new Type[] { queryableData.ElementType },
                                                            queryableData.Expression,
                                                            Expression.Lambda<Func<Person, bool>>(e1, new ParameterExpression[] { inputParam }));
    //execute and return
    return queryableData.Provider.CreateQuery<Person>(whereCallExpression);
}

private void test()
{
	Filter(typeof(Person).GetProperty("FirstNameIsActive"), true);
    Filter(typeof(Person).GetProperty("SecondNameIsActive"), true);
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы