常量

1、值常量  (p)=>100+88+p

   ParameterExpression par = Expression.Parameter(typeof(int), "p");
BinaryExpression binaryexp = Expression.Add(Expression.Constant(100), Expression.Constant(88));//值类型常数
BinaryExpression parAndi = Expression.Add(binaryexp, par); LambdaExpression m2 = Expression.Lambda(parAndi, par);//LambdaExpression.Compile() 方法返回 Delegate 类型。 必须将其转换为正确的委托类型,执行的效率非常慢,不如泛型 Console.WriteLine(m2.Compile().DynamicInvoke(2));//执行的效率非常慢,不如泛型

2、字符串常量  ()=>"100"+"88"

构造类型为LambdaExpression的lambda表达式树,编译后得到委托的基元类型(弱类型)。

            MethodInfo mInfo = typeof(String).GetMethod("Concat", new Type[] { typeof(String), typeof(String) });//第一步:获取Concat方法的MethodInfo

           BinaryExpression binaryexp = Expression.Add(Expression.Constant("100"), Expression.Constant("88"), mInfo);//将方法传递给 Expression.Add

            LambdaExpression lb = Expression.Lambda(binaryexp);
Console.WriteLine(lb.Compile().DynamicInvoke());//执行的效率非常慢,不如泛型

但这时会报错 “没有为类型“System.String”和“System.String”定义二进制运算符 Add”,这是怎么回事,在我们代码时如果写 string s= "100"+"88";是没错的啊。实际上字串的 +  在生成IL代码时,会转换成 string 的 Concat 扩展方法来操作。因此要实现如  "100"+"88" 还是稍显麻烦

第一步:获取Concat方法的MethodInfo

第二步:将方法传递给 Expression.Add

变量

//Assign    创建一个表示赋值运算的 BinaryExpression。
void AssignSample()
{
ParameterExpression variableAssignExpr = Expression.Variable(typeof(String), "sampleVar");
Expression assignSimpleExpr = Expression.Assign(
variableAssignExpr,
Expression.Constant("Hello World!")
);
Expression blockAssignExpr = Expression.Block(
new ParameterExpression[] { variableAssignExpr },
assignSimpleExpr
);
Console.WriteLine(assignSimpleExpr.ToString());//(sampleVar = "Hello World!")
Console.WriteLine(Expression.Lambda<Func<String>>(blockAssignExpr).Compile()());//Hello World!
}
AssignSample();

创建数组

NewArrayInit 创建一个表示创建一维数组并使用元素列表初始化该数组的 NewArrayExpression

    //NewArrayInit    创建一个表示创建一维数组并使用元素列表初始化该数组的 NewArrayExpression。
void NewArrayInitSample()
{
List<Expression> trees = new List<Expression>() {
Expression.Constant("oak"),
Expression.Constant("fir"),
Expression.Constant("spruce"),
Expression.Constant("alder")
}; NewArrayExpression newArrayExpression = Expression.NewArrayInit(typeof(string), trees);
newArrayExpression.ToString().Dump("NewArrayInit");
}
NewArrayInitSample();

NewArrayBounds 创建一个表示创建具有指定秩的数组的 NewArrayExpression

    //NewArrayBounds   创建一个表示创建具有指定秩的数组的 NewArrayExpression。
void NewArrayBoundsSample()
{
NewArrayExpression newArrayExpression = Expression.NewArrayBounds(
typeof(string),
Expression.Constant(3),
Expression.Constant(2)
);
newArrayExpression.ToString().Dump("NewArrayBounds");//new System.String[,](3, 2)
}
NewArrayBoundsSample();

类型转换

算术运算符

Add(Expression, Expression) 创建一个表示不进行溢出检查的算术加法运算的

public class Plus
{
//下面表达式指定加法的实现
public static int AddOne(int a, int b)
{
return a + b + 1;
}
}
//Add(Expression, Expression) 创建一个表示不进行溢出检查的算术加法运算的 BinaryExpression。
void AddSample()
{
Expression sumExpr = Expression.Add(Expression.Constant(1), Expression.Constant(2));
Console.WriteLine(sumExpr.ToString());//(1+2)
Console.WriteLine(Expression.Lambda<Func<int>>(sumExpr).Compile()());//3
Expression sumExpr2 = Expression.Add(Expression.Constant(1), Expression.Constant(2), typeof(Plus).GetMethod("AddOne"));
Console.WriteLine(sumExpr2.ToString());
Console.WriteLine(Expression.Lambda<Func<int>>(sumExpr2).Compile()());
}
AddSample();

 Expression.Coalesce

xiaoli ?? xiaoi

  BinaryExpression bin = Expression.Coalesce(Expression.Parameter(typeof(string), "xiaoli"), Expression.Parameter(typeof(string), "xiaoi"));

引用地址 Expression.ReferenceEqual  Expression.ReferenceNotEqual

            BinaryExpression bin2 = Expression.ReferenceEqual(Expression.Parameter(typeof(string), "xiaoli"), Expression.Parameter(typeof(string), "xiaoi"));
BinaryExpression bin = Expression.ReferenceNotEqual(Expression.Parameter(typeof(string), "xiaoli"), Expression.Parameter(typeof(string), "xiaoi"));

赋值运算符

 

ParameterExpression i = Expression.Parameter(typeof(int), "i");
BlockExpression block = Expression.Block(
new[] { i },
//赋初值 i=5
Expression.Assign(i, Expression.Constant(5, typeof(int))),
//i+=5 10
Expression.AddAssign(i, Expression.Constant(5, typeof(int))),
//i-=5 5
Expression.SubtractAssign(i, Expression.Constant(5, typeof(int))),
//i*=5 25
Expression.MultiplyAssign(i, Expression.Constant(5, typeof(int))),
//i/=5 5
Expression.DivideAssign(i, Expression.Constant(5, typeof(int)))
);
Console.WriteLine(Expression.Lambda<Func<int>>(block).Compile()());

Assign 创建一个表示赋值运算的 BinaryExpression。

//Assign    创建一个表示赋值运算的 BinaryExpression。
void AssignSample()
{
ParameterExpression variableAssignExpr = Expression.Variable(typeof(String), "sampleVar");
Expression assignSimpleExpr = Expression.Assign(
variableAssignExpr,
Expression.Constant("Hello World!")
);
Expression blockAssignExpr = Expression.Block(
new ParameterExpression[] { variableAssignExpr },
assignSimpleExpr
);
Console.WriteLine(assignSimpleExpr.ToString());//(sampleVar = "Hello World!")
Console.WriteLine(Expression.Lambda<Func<String>>(blockAssignExpr).Compile()());//Hello World!
}
AssignSample();

AddAssign(Expression, Expression) 创建一个表示不进行溢出检查的加法赋值运算的 BinaryExpression

    //AddAssign(Expression, Expression) 创建一个表示不进行溢出检查的加法赋值运算的 BinaryExpression
void AddAssignSample()
{
ParameterExpression variableExpr = Expression.Variable(typeof(int), "sampleVar");//the parameter expression is used to create a variable;
BlockExpression addAssignExpr = Expression.Block(
new ParameterExpression[] { variableExpr },
Expression.Assign(variableExpr, Expression.Constant(1)),
Expression.AddAssign(
variableExpr,
Expression.Constant(2)
)
);
addAssignExpr.Expressions.ForEach(p => p.ToString().Dump());//(sampleVar = 1),(sampleVar +=2)
Console.WriteLine(Expression.Lambda<Func<int>>(addAssignExpr).Compile()());//3
}
AddAssignSample();

AddAssign(Expression, Expression, MethodInfo) 创建一个表示不进行溢出检查的加法赋值运算的 BinaryExpression。可指定实现

    //AddAssign(Expression, Expression, MethodInfo)  创建一个表示不进行溢出检查的加法赋值运算的 BinaryExpression。可指定实现
//参Add(Expression, Expression, MethodInfo) //AddAssign(Expression, Expression, MethodInfo, LambdaExpression) 创建一个表示不进行溢出检查的加法赋值运算的 BinaryExpression。可指定实现, 可指定类型转换函数

AddAssignChecked(Expression, Expression) 创建一个表示进行溢出检查的加法赋值运算的 BinaryExpression。

    //AddAssignChecked(Expression, Expression)    创建一个表示进行溢出检查的加法赋值运算的 BinaryExpression。
void AddAssignCheckedSample()
{
ParameterExpression variableExprWithChecked = Expression.Variable(typeof(int), "sampleVar");//the parameter expression is used to create a variable;
BlockExpression addAssignExprWithChecked = Expression.Block(
new ParameterExpression[] { variableExprWithChecked },
Expression.Assign(variableExprWithChecked, Expression.Constant(2147483647)),
Expression.AddAssign(
variableExprWithChecked,
Expression.Constant(1)
)
);
addAssignExprWithChecked.Expressions.ForEach(p => p.ToString().Dump());//(sampleVar = 2147483647),(sampleVar +=1)
Console.WriteLine(Expression.Lambda<Func<int>>(addAssignExprWithChecked).Compile()());//-2147483648
}
AddAssignCheckedSample(); //AddChecked(Expression, Expression) 创建一个表示进行溢出检查的算术加法运算的 BinaryExpression。
//同Add

NotEqual 创建一个表示不相等比较的 BinaryExpression。

    //NotEqual   创建一个表示不相等比较的 BinaryExpression。
void NotEqualSample()
{
Expression notEqualExpr = Expression.NotEqual(Expression.Constant(1), Expression.Constant(2));
notEqualExpr.ToString().Dump("NotEqualExpr");//(1!=2)
Expression.Lambda<Func<bool>>(notEqualExpr).Compile()().Dump("NotEqual");//true
}
NotEqualSample(); //OnesComplement 返回表示一的补数的表达式。//TODO

关系运算符

逻辑运算符

Not 创建一个表示按位求补运算的 UnaryExpression。

    //Not   创建一个表示按位求补运算的 UnaryExpression。
void NotSample()
{
Expression notExpr = Expression.Not(Expression.Constant(true));
notExpr.ToString().Dump("NotExpr");//Not(true)
Expression.Lambda<Func<bool>>(notExpr).Compile()().Dump("Not");//false
}
NotSample();

调用方法

调用静态方法,构建表达式树:(x,y)=>Math.Sin(x)+Math.Cos(y)

ParameterExpression ParmsX=Expression.Parameter(typeof(double),"x"); //参数X   

ParameterExpression ParmsY=Expression.Parameter(typeof(double ),"y");  //参数Y  

var left=Expression.Call(typeof(Math).GetMethod("Sin"),ParmsX);  //树左边节点  

var right=Expression.Call(null,typeof(Math).GetMethod("Cos"),ParmsY);//调用静态方法这样写也可以,树右边节点  

var body=Expression.Add(left,right);  //合成表达式树主体  

LambdaExpression lambda=Expression.Lambda<Func<double,double,double>>(body,new ParameterExpression []{ParmsX,ParmsY});
//转成的表达式树,在编译后,就可以调用委托所指向的方法。

 调用实例方法,

ParameterExpression x =Expression.Parameter(typeof(string), "x");
Expression body = Call( x, typeof(string).GetMethod("StartsWith", new[] { typeof(string) })!, Constant("a"));
Expression<Func<string, bool>> expr = Expression.Lambda<Func<string, bool>>(body, x);

Block

block相当于匿名函数,其返回表达式是最后一个表达式决定。如果有变量,那么就要通过new[]{变量}传入变量,再嵌套的block中可以使用外部的的变量,例如for 功能中的示例

无变量block

.Block() {
    .Call System.Console.Write("你好!");
    .Call System.Console.WriteLine("BlockExpression表达式!");
    42;
    .Call System.String.Concat("测试1 ","测试2")
}

 //声明一个包含有4个表达式的表达式块。
BlockExpression blockExpr = Expression.Block(
Expression.Call(null, typeof(Console).GetMethod("Write", new Type[] { typeof(String) }), Expression.Constant("你好!")),// 1
Expression.Call(null, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(String) }),Expression.Constant("BlockExpression表达式!")),
Expression.Constant(42),
Expression.Call(null, typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string) }), Expression.Constant("测试1 "), Expression.Constant("测试2")) //4
);
Console.WriteLine("***********************");
Console.WriteLine("显示表达示块的执行结果:"); // 首先创建表达式树,
// 编译,执行.
var result2 = Expression.Lambda<Func<string>>(blockExpr).Compile();
result2();
var result = Expression.Lambda<Func<string>>(blockExpr).Compile()();

 有参数block,block相当于匿名函数,如果有变量,那么就要通过new[]{变量}传入变量,由于是匿名函数 所以也会有返回值,返回值就是最有一个表达式的值

.Block(System.String $name,  System.String $fomt)
{
    $fomt = "名字:{0}";
    $name = "xiaoli";
    .Call System.String.Format( $fomt,$name)
}

    ParameterExpression pa = Expression.Parameter(typeof(string), "name");
ParameterExpression ex = Expression.Parameter(typeof(string), "fomt");
BlockExpression blo = Expression.Block(
//块内不能定义参数 类似这样是错误的 ParameterExpression ex = Expression.Parameter(typeof(string), "fomt");
new[] { pa, ex },
Expression.Assign(ex, Expression.Constant("名字:{0}")),
Expression.Assign(pa,Expression.Constant("xiaoli" )),
Expression.Call(typeof(string).GetMethod("Format",new[] { typeof(string),typeof(string)}),ex,pa) );
Console.WriteLine(Expression.Lambda(blo).Compile().DynamicInvoke() );

判断语句

 三目运算符(Expression.Condition):?:   的应用 由于不是block那样的函数,所以可以直接使用外部的parameter定义的变量

() => {
    int a;
    int b;
    a = 10;
    b = 30;
    return a == b ? "a和b相等" : "a与b不相等";//这个就是Expression.Condition
}

将以上格式转换化成 表达式树 如下:

ParameterExpression aiP1 = Expression.Parameter(typeof(int), "a"); //(1)
ParameterExpression aiP2 = Expression.Parameter(typeof(int), "b");
ParameterExpression aiP3 = Expression.Parameter(typeof(int));
Console.WriteLine(aiP3.ToString());
//输出:Param_0
BinaryExpression aiBnExp = Expression.MakeBinary(ExpressionType.Equal,
aiP1,
aiP2); ConditionalExpression aiCdExp = Expression.Condition(
aiBnExp,
Expression.Constant("a和b相等"),
Expression.Constant("a与b不相等")
); //(2) Console.WriteLine(aiCdExp.ToString());
//输出:IIF((a == b), "a和b相等", "a与b不相等") LambdaExpression aiLamExp = Expression.Lambda(
Expression.Block //(3)
(
new ParameterExpression[] { aiP1, aiP2 }
, Expression.Assign(aiP1, Expression.Constant(10))
, Expression.Assign(aiP2, Expression.Constant(30))
, aiCdExp ));
Console.WriteLine(aiLamExp.Compile().DynamicInvoke()); Console.ReadLine();

2、Expression.IfThen

代码的效果如下:

.If ( $i % 2 == 0)
 {
    .Call System.Console.WriteLine($i)
}
 

 ParameterExpression i = Expression.Parameter(typeof(int), "i");
ConditionalExpression con= Expression.IfThen( Expression.Equal( Expression.Modulo(i, Expression.Constant(2, typeof(int))), Expression.Constant(0, typeof(int))),
Expression.Call(typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) }), new[] { i }) );

3、Expression.IfThenElse

样式如下

if (value > 1) {
    result *= value--;
} else {
    result %= value--;
}

写成代码

     ParameterExpression value = Expression.Parameter(typeof(int), "value");
//本地变量
ParameterExpression result = Expression.Parameter(typeof(int), "result");
ConditionalExpression ifthenelse= Expression.IfThenElse( Expression.GreaterThan(value, Expression.Constant(1)), Expression.MultiplyAssign(result, Expression.PostDecrementAssign(value)),
Expression.ModuloAssign(result, Expression.PostDecrementAssign(value)));

 4、for循环的实现

Expression<Action> lambdaExpression2 = () =>
{
for (int i = 1; i <= 10; i++)
{
Console.WriteLine("Hello");
}
};

再expression tree visual看到的效果
() => {
    int index;
    index = 1;
    while (true) {
        if (index <= 10) {
            Console.WriteLine("Hello");
            index++;
        } else {
            break;
        }
    };
}
LabelTarget labelBreak = Expression.Label();
ParameterExpression loopIndex = Expression.Parameter(typeof(int), "index"); BlockExpression block = Expression.Block(
new[] { loopIndex },
// 初始化loopIndex =1
Expression.Assign(loopIndex, Expression.Constant(1)),
Expression.Loop(
Expression.IfThenElse(
// if 的判断逻辑
Expression.LessThanOrEqual(loopIndex, Expression.Constant(10)),
// 判断逻辑通过的代码
Expression.Block(
Expression.Call(
null,
typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }),
Expression.Constant("Hello")),
Expression.PostIncrementAssign(loopIndex)),
// 判断不通过的代码
Expression.Break(labelBreak)
),labelBreak)); // 将我们上面的代码块表达式
Expression<Action> lambdaExpression = Expression.Lambda<Action>(block);
lambdaExpression.Compile().Invoke();

5、SwitchExpression

表示一个控制表达式,该表达式通过将控制传递到 SwitchCase 来处理多重选择。

//构建类似下列代码的表达式
//int i = 1;
//switch (i)
//{
// case 1:
// Console.WriteLine("一等奖");
// break;
// case 2:
// Console.WriteLine("二等奖");
// break;
// case 3:
// Console.WriteLine("三等奖");
// break;
// default:
// Console.WriteLine("鼓励奖");
// break;
//}
/声明 SwitchCase 的称值参数,相当于 switch (i)
ParameterExpression aiSwvP = Expression.Parameter(typeof(int), "i"); //构造
SwitchExpression aiSwvExp = Expression.Switch(
aiSwvP // switch (i)
, Expression.Call(
null,
typeof(Console).GetMethod("WriteLine", new Type[] { typeof(String) }),
Expression.Constant("鼓励奖")
) //default 默认事例,此参数没有代码无默认事例 , new SwitchCase[] { //事例 之一,前部分是执行,后部分是合符条件值(与) Expression.SwitchCase( Expression.Call(
null,
typeof(Console).GetMethod("WriteLine", new Type[] { typeof(String) }),
Expression.Constant("一等奖") )
, Expression.Constant(1) //case 1
)
,Expression.SwitchCase(
Expression.Call(
null,
typeof(Console).GetMethod("WriteLine", new Type[] { typeof(String) }),
Expression.Constant("二等奖") ),
Expression.Constant(2) //case 2
)
,Expression.SwitchCase(
Expression.Call(
null,
typeof(Console).GetMethod("WriteLine", new Type[] { typeof(String) }),
Expression.Constant("三等奖") )
,Expression.Constant(3) //case 3
)
}); // The following statement first creates an expression tree,
// then compiles it, and then runs it.
Expression.Lambda<Action>(switchExpr).Compile()(); Expression.Lambda<Action<int>>(aiSwvExp, aiSwvP).Compile().DynamicInvoke(2);

循环语句

(
    int result,
    result = 1,
    while (true) {
        if (value > 1) {
            result *= value--;
        } else {
            break result;
        }
    }
)

以下完成这个语句块。 该语句快默认是  while (true) 所以要跳出循环的语句。

//参数value
ParameterExpression value = Expression.Parameter(typeof(int), "value");
//本地变量
ParameterExpression result = Expression.Parameter(typeof(int), "result");
//标签,用来跳出循环
LabelTarget label = Expression.Label(typeof(int));
//创建表达式块
BlockExpression block = Expression.Block(
//添加本地参数result
new[] { result },
//result=1 赋值
Expression.Assign(result, Expression.Constant(1)),
//循环
Expression.Loop(
//循环条件
Expression.IfThenElse(
//如果 value>1
Expression.GreaterThan(value, Expression.Constant(1)),
//则 result*=value--;
Expression.MultiplyAssign(result, Expression.PostDecrementAssign(value)),
//否则跳出loop循环。跳到label的语句执行
Expression.Break(label, result)//跳出循环并且 返回值 result
),
label
)
);
//编译表达式树
Func<int, int> factor = Expression.Lambda<Func<int, int>>(block, value).Compile();
//执行,输出结果120
Console.WriteLine(factor(5));

分析:句法  public static LoopExpression Loop(Expression body, LabelTarget? @break);

body :表达式主体       @break:推出的位置

public static ConditionalExpression IfThenElse(Expression test, Expression ifTrue, Expression ifFalse);

异常处理try 块中的 catch 语句

CatchBlock类:表示 try 块中的 catch 语句。
  单独的CatchBlock是没有意义的,他必需和TryExpression一起使用才有用。
  TryExpression类:表示 try/catch/finally/fault 块。
  构建如下表达式:(try {} Catch {})

TryExpression tryCatchExpr = Expression.TryCatch(
Expression.Block(
Expression.Divide(Expression.Constant(50), Expression.Constant(2)),
Expression.Constant("无异常返回")
),
Expression.Catch(
typeof(DivideByZeroException),
Expression.Constant("异常返回")
)
);
Console.WriteLine(Expression.Lambda<Func<string>>(tryCatchExpr).Compile()()); //输出为 :无异常返回  将上面的 Expression.Constant(2),更改为 Expression.Constant(0)

如果无法判断异常类型,刚将typeof(DivideByZeroException),换成  typeof(Exception);

  如要增加 Finally,则用 TryCatchFinally 构建:

TryExpression tryCatchExpr2 = Expression.TryCatchFinally(
Expression.Block(
Expression.Divide(Expression.Constant(50), Expression.Constant(2)),
Expression.Constant("无导常返回")
),
Expression.Call(typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }),
    Expression.Constant("Finally 块")),
Expression.Catch(typeof(Exception), Expression.Constant("导常返回")
)
);
Console.WriteLine(Expression.Lambda<Func<string>>(tryCatchExpr2).Compile()());

UnaryExpression :表示包含一元运算符的表达式。

如:

      

 UnaryExpression aiU1 = Expression.Negate(Expression.Constant(100));

            Console.WriteLine(aiU1.ToString());

            //Not(Ture)
UnaryExpression aiU2 = Expression.Not(Expression.Constant(true));
Console.WriteLine(aiU2.ToString()); //() => 123456
UnaryExpression aiU3 = Expression.Quote(Expression.Lambda( Expression.Constant(123456)));
Console.WriteLine(aiU3.ToString()); //(123456 As Nullable`1)
UnaryExpression aiU4 = Expression.TypeAs(Expression.Constant(123456), typeof(int?));
Console.WriteLine(aiU4.ToString()); //Convert(123456)
UnaryExpression aiU5 = Expression.Convert(Expression.Constant(123456), typeof(Int16));
Console.WriteLine(aiU5.ToString());
//+123456
UnaryExpression aiU6 = Expression.UnaryPlus(Expression.Constant(123456));
Console.WriteLine(aiU6.ToString());

属性

par.Name == "xiaoli"

以上写成表达树节点式代码如下:

 static void Main(string[] args)
{
ParameterExpression par = Expression.Parameter(typeof(People),"par");
MemberExpression property = Expression.Property(par, "Name");
BinaryExpression binary = Expression.Assign(property, Expression.Constant("xiaoming"));
BinaryExpression eqb = Expression.Equal(property,Expression.Constant("xiaoli")); } public class People
{
public int Age { get; set; }
public string Name { get; set; } public int Id; }

扩展

InvocationExpression

说明:Expression.Invoke方法是对lbamda表达式的调用并且传入实参,其实就是labmda表达式树的再次封装。以下是Expression.Invoke方法应用实例

案例一、实现扩展方法

public static Func<T, bool> Or<T>(this Func<T, bool> expr1, Func<T, bool> expr2)
{
return x => expr1(x) || expr2(x);
}

具体代码:

public static Expression<Func<T, bool>> Or<T>(
this Expression<Func<T, bool>> expr1, Expression<Func<T, bool>> expr2)
{
var parameter = Expression.Parameter(typeof(T), "x");
var invokedExpr1 = Expression.Invoke(expr1, parameter);
var invokedExpr2 = Expression.Invoke(expr2, parameter); return Expression.Lambda<Func<T, bool>>(
Expression.OrElse(invokedExpr1, invokedExpr2), parameter);
}

案例二、调用表达式树并且传入参数

Expression<Func<int, int, bool>> largeSumTest =
(num1, num2) => (num1 + num2) > 1000; InvocationExpression invocationExpression= Expression.Invoke(
largeSumTest,
Expression.Constant(539),
Expression.Constant(281)); Console.WriteLine(invocationExpression.ToString());
// Invoke((num1, num2) => ((num1 + num2) > 1000),539,281)

案例三、

 static void Main(string[] args)
{ List<Person> PersonLists = new List<Person>()
{
new Person { Name = "张三",Age = 20,Gender = "男",
Phones = new List<Phone> {
new Phone { Country = "中国", City = "北京", Name = "小米" },
new Phone { Country = "中国",City = "北京",Name = "华为"},
new Phone { Country = "中国",City = "北京",Name = "联想"},
new Phone { Country = "中国",City = "台北",Name = "魅族"},
}
},
new Person { Name = "松下",Age = 30,Gender = "男",
Phones = new List<Phone> {
new Phone { Country = "日本",City = "东京",Name = "索尼"},
new Phone { Country = "日本",City = "大阪",Name = "夏普"},
new Phone { Country = "日本",City = "东京",Name = "松下"},
}
},
new Person { Name = "克里斯",Age = 40,Gender = "男",
Phones = new List<Phone> {
new Phone { Country = "美国",City = "加州",Name = "苹果"},
new Phone { Country = "美国",City = "华盛顿",Name = "三星"},
new Phone { Country = "美国",City = "华盛顿",Name = "HTC"}
}
}
}; Expression<Func<Person, bool>> lambdaone = ex => ex.Name.Equals("张三"); Expression<Func<Person, bool>> lambdatwo = ex => ex.Age == 30;
// 创建参数表达式
var ss = lambdatwo.Parameters.Cast<Expression>();
/* Parameters.Cast 是强制转化 将 ReadOnlyCollection<ParameterExpression>转成 IEnumerable<TResult>
表达式树里面再套表达式树*/
InvocationExpression invocation = Expression.Invoke(lambdaone, lambdatwo.Parameters.Cast<Expression>()); // 创建or运算
BinaryExpression binary = Expression.Or(lambdatwo.Body, invocation);
// 生成lambda表达式
var exp = Expression.Lambda<Func<Person, bool>>(binary, lambdatwo.Parameters);
var Lists = PersonLists.Where(exp.Compile());
foreach (var List in Lists)
{
Console.WriteLine(List.Name);
}
Console.Read(); } public class Phone
{
public string Country { get; set; }
public string City { get; set; }
public string Name { get; set; }
}
public class Person
{
public string Name { get; set; }
public string Gender { get; set; }
public int Age { get; set; }
public List<Phone> Phones { get; set; } }

【C#表达式树 五】工厂模式创建表达式树节点的更多相关文章

  1. PHP模式设计之单例模式、工厂模式、注册树模式、适配器模式、观察者模式

    php模式设计之单例模式 什么是单例模式? 单例模式是指在整个应用中只有一个实例对象的设计模式 为什么要用单例模式? php经常要链接数据库,如果在一个项目中频繁建立连接数据库,会造成服务器资源的很大 ...

  2. 设计模式(三): FACTORY工厂模式 -- 创建型模式

    1.定义 定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method使一个类的实例化延迟到了子类. 2.适用场景 1.第一种情况是对于某个产品,调用者清楚地知道应该使用哪个具体 ...

  3. 设计模式(四):SIMPLE FACTORY简单工厂模式 -- 创建型模式

    1.定义 简单工厂模式又称静态工厂方法模式.重命名上就可以看出这个模式一定很简单.它存在的目的很简单:定义一个用于创建对象的接口. 2.适用场景 如果一个客户要一款宝马车,一般的做法是客户去创建一款宝 ...

  4. 设计模式(一): abstract factory抽象工厂模式 -- 创建型模式

    1.定义 为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类. 2.适用场景 1.一个系统要独立于它的产品创建.组合和表示. 2.一个系统要由多个产品系列中的一个来配置. 3.当你要 ...

  5. 设计模式(3)--SimpleFactory( [1] 简单工厂模式)--创建型

    1.模式定义: 简单工厂模式是类的创建模式,又叫做静态工厂方法(Static Factory Method)模式.简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例. 2.模式特点: 实现方式的 ...

  6. 设计模式(4)--AbstractFactory(抽象工厂模式)--创建型

    1.模式定义: 抽象工厂是应对产品族概念的,提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们的具体类 2.模式特点: 抽象工厂模式为创建一组对象提供了一种解决方案.与工厂方法模式相比,抽象工 ...

  7. AbstractFactory抽象工厂模式(创建型模式)

    1.new 的问题 常见的对象创建方法: //创建一个Road对象 Road road=new Road(); new的问题:实现依赖,不能应对具体实例的变化 怎么理解上面这句话呢? 可以这样理解:我 ...

  8. C#设计模式--工厂模式(创建型模式)

    一.简单工厂模式(UML类图): 核心类代码: public class Calc { public double NumberA { get; set; } public double Number ...

  9. C#设计模式--抽象工厂模式(创建型模式)

    一.抽象工厂模式: 在工厂模式中具体的产品和具体的工厂是一一对应的,一个工厂只能生产一种产品,结构单一,例如小米公司刚开始是只生产小米手机,但是伴随着公司的发展,他们需要生产不同型号的手机,也会生产路 ...

随机推荐

  1. .Net Core依赖注入

    一.配置文件的读取 利用Startup类中的configuration读取appsettings.json中的配置 { "Logging": { "LogLevel&qu ...

  2. JAVA主要类集分类

    包装类 Integer包装类 方法 返回值 功能描述 byteValue() byte 以 byte 类型返回该 Integer 的值 intValue() int 以 int 型返回此 Intege ...

  3. Tomcat-如何创建动态的web工程及目录介绍

    1,IDEA中如何创建动态web工程 (1)创建一个新模块 (2)选择你要创建什么类型的模块 (3)输入模块名,finish完成创建 创建成功如下图: 一般在WEB-INF下建一个lib目录 存放ja ...

  4. asyncio和aiohttp

    asyncio官网 https://docs.python.org/zh-cn/3/library/asyncio-task.html 下面为伪代码: import aiohttp import as ...

  5. 别人都在认真听课,而我埋头写Python为主播疯狂点点点点点赞!

    最近有次在钉钉看直播,发现这个直播非常之精彩,于是情不自禁地想要为主播大佬连刷一波赞: 但我发现,手动连击点赞速度十分不可观.气人的是,钉钉直播不能长按刷赞!这让我很恼怒.心中满怀的激动和兴奋以及对大 ...

  6. 对于网络请求ajax理解

    先对原生Ajax进行理解: Ajax=异步JS和XML,用于创建快速动态网页的技术 可以使网页实现异步更新.这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新. 工作原理 对于Ajax的 ...

  7. UTF-8与UTF-8(BOM)区别

    感谢原文作者:Teingi 原文链接:https://blog.csdn.net/weixin_40449300/article/details/86567129 在我们通常使用的windows系统中 ...

  8. textarea自适应高(宽)度

    转载请注明来源:https://www.cnblogs.com/hookjc/ 方法一: <textarea rows=1 cols=40 style='overflow:scroll;over ...

  9. 入门-k8s集群环境搭建(二)

    对于 Kubernetes 初学者,在搭建K8S集群时,推荐在阿里云或腾讯云采购如下配置:(您也可以使用自己的虚拟机.私有云等您最容易获得的 Linux 环境) 至少2台 2核4G 的服务器 Cent ...

  10. iOS中属性 (nonatomic, copy, strong, weak)的使用 By hL

    以下内容来自Stackflow的详解 1.Nonatomicnonatomic is used for multi threading purposes. If we have set the non ...