表达式树是一种数据结构,以数据形式表示语言级代码。.Net平台引入的"逻辑即数据"概念。
所有的数据都存储在树结构中,每个结点表示一个表达式(Expression)。要想手动生成表达式树我们需要引用System.Linq.Expressions 命名空间,最重要的一个类是Expression,它是所有表达式的基类。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Reflection;
namespace fofo.ExpressionTree
{
public class ExpressionWhere
{
private class UserInfo
{
public string Name { get; set; }
public int Age { get; set; }
}
///
/// build: info => ((info.Name.Contains("en")) And info.Age > 10 And info.Age < 20)
///
private Expression<Func<UserInfo, bool>> BuildExpressionTree()
{
// condition Name Contains "en" and Age > 10 and Age < 20
Expression where;
// parameter UserInfo
ParameterExpression par = Expression.Parameter(typeof(UserInfo), "info");
// get property (Name)
MemberExpression memName = Expression.Property(par, "Name");
MethodInfo methodContains = typeof(string).GetMethod("Contains");
ConstantExpression constExpress = Expression.Constant("en", typeof(string));
MethodCallExpression callExpress = Expression.Call(memName, methodContains, constExpress);
where = callExpress;
// get property (Age)
MemberExpression memAge = Expression.Property(par, "Age");
ConstantExpression age1 = Expression.Constant(10, typeof(int));
BinaryExpression greaterThan = Expression.GreaterThan(memAge, age1);
where = Expression.And(where, greaterThan);
ConstantExpression age2 = Expression.Constant(20, typeof(int));
BinaryExpression lessThan = Expression.LessThan(memAge, age2);
where = Expression.And(where, lessThan);
Expression<Func<UserInfo, bool>> lambda = Expression.Lambda<Func<UserInfo, bool>>(where, par);
//Func<UserInfo, bool> func = lambda.Compile();
return lambda;
}
public string TestBuildExpressionTree()
{
Expression<Func<UserInfo, bool>> lambda = BuildExpressionTree();
string strRet = lambda.ToString() + "\r\n";
Func<UserInfo, bool> func = lambda.Compile();
List<UserInfo> listUser = new List<UserInfo>();
for (int i = 5; i < 25; i++)
{
listUser.Add(new UserInfo { Name = "leng", Age = i });
}
IEnumerable<UserInfo> listTmp = listUser.Where<UserInfo>(func);
foreach (UserInfo info in listTmp)
{
strRet += info.Age.ToString() + "\r\n";
}
return strRet;
}
}
}