2013-11-28 30 views
2

例子中,我下面的代碼lambda exprssion的動態變化體?

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

如果我想通過屬性過濾FirstNameIsActive

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

如果我想通過屬性過濾SecondNameIsActive

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

我想在運行時改變我謂詞到

Func<Person, bool> predicate = x => x.PropertyThatIWant == true; 
+0

你想如何使用它? – Grundy

回答

2

您可以利用修改的閉包。

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

而且我的解決方案

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