Question

Example I have following code

public class Person
{
    public bool FirstNameIsActive { get; set; }
    public bool SecondNameIsActive { get; set; }
}    

If i want to filter by property FirstNameIsActive

Func<Person, bool> predicate1 = x => x.FirstNameIsActive == true;

If i want to filter by property SecondNameIsActive

Func<Person, bool> predicate2 = x => x.SecondNameIsActive == true;

I want change in runtime my predicate to

Func<Person, bool> predicate = x => x.PropertyThatIWant == true;
Was it helpful?

Solution

You can take advantage of a modified closure.

//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

OTHER TIPS

And my solution

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);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top