I
I
isxaker2013-11-28 15:46:13
.NET
isxaker, 2013-11-28 15:46:13

How to change lambda expression in runtime?

I have a code example like this

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);
}

How to avoid duplicating code in a method filter()? That is, I need something like
predicate = x => x.PROPERTY == isActive;

Answer the question

In order to leave comments, you need to log in

3 answer(s)
I
isxaker, 2013-11-28
@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

V
veitmen, 2013-11-28
@veitmen

I would advise looking at DynamicLinq.
Read more here.

I
isxaker, 2013-11-28
@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);
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question