• C# 表达式树 Expression


    表达式树是定义代码的数据结构。 它们基于编译器用于分析代码和生成已编译输出的相同结构。

    几种常见的表达式

    BinaryExpression 包含二元运算符的表达式

     1                 BinaryExpression binaryExpression = Expression.MakeBinary(ExpressionType.Add,Expression.Constant(1),Expression.Constant(2));
     2                 Console.WriteLine(binaryExpression.ToString());//(1+2) 不进行溢出检查
     3                 binaryExpression = Expression.MakeBinary(ExpressionType.AddChecked, Expression.Constant(3), Expression.Constant(4));
     4                 Console.WriteLine(binaryExpression.ToString());//(3+4) 进行溢出检查
     5                 binaryExpression = Expression.MakeBinary(ExpressionType.Subtract, Expression.Constant(5), Expression.Constant(6));
     6                 Console.WriteLine(binaryExpression.ToString());//(5-6) 不进行溢出检查
     7                 binaryExpression = Expression.MakeBinary(ExpressionType.SubtractChecked, Expression.Constant(7), Expression.Constant(8));
     8                 Console.WriteLine(binaryExpression.ToString());//(7-8) 进行溢出检查
     9                 binaryExpression = Expression.MakeBinary(ExpressionType.Multiply, Expression.Constant(9), Expression.Constant(10));
    10                 Console.WriteLine(binaryExpression.ToString());//(9*10) 不进行溢出检查
    11                 binaryExpression = Expression.MakeBinary(ExpressionType.MultiplyChecked, Expression.Constant(11), Expression.Constant(12));
    12                 Console.WriteLine(binaryExpression.ToString());//(11*12) 进行溢出检查
    13                 binaryExpression = Expression.MakeBinary(ExpressionType.Divide, Expression.Constant(13), Expression.Constant(14));
    14                 Console.WriteLine(binaryExpression.ToString());//(13/14) 
    15                 binaryExpression = Expression.MakeBinary(ExpressionType.Modulo, Expression.Constant(15), Expression.Constant(16));
    16                 Console.WriteLine(binaryExpression.ToString());//(15%16) 
    View Code

    BlockExpression 包含一个表达式序列的块,表达式中可定义变量

     1                 BlockExpression blockExpr = Expression.Block(
     2                      Expression.Call(null, typeof(Console).GetMethod("Write", new Type[] { typeof(String) }), Expression.Constant("Hello ")),
     3                      Expression.Call(null, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(String) }), Expression.Constant("World!")),
     4                      Expression.Constant(42)
     5                 );
     6                 var result = Expression.Lambda<Func<int>>(blockExpr).Compile()();
     7                 Console.WriteLine("**************************");
     8                 foreach (var expr in blockExpr.Expressions)
     9                     Console.WriteLine(expr.ToString());
    10                 Console.WriteLine("**************************");
    11                 Console.WriteLine(result);
    View Code

    程序执行结果

    ConditionalExpression 具有条件运算符的表达式

    Expression conditionExpr = Expression.Condition(Expression.Constant(num > 10),Expression.Constant("num is greater than 10"),Expression.Constant("num is smaller than 10"));

    ConstantExpression 具有常数值的表达式

    1 Expression.Constant(5.5);
    2 Expression.Constant("Hello World!");
    View Code

    DefaultExpression 类型或空表达式的默认值

    1                 Expression defaultExpr = Expression.Default(typeof(byte));
    2 
    3                 // Print out the expression.
    4                 Console.WriteLine(defaultExpr.ToString());//  等价于 default(byte)
    5 
    6                 // The following statement first creates an expression tree,
    7                 // then compiles it, and then executes it.
    8                 Console.WriteLine(Expression.Lambda<Func<byte>>(defaultExpr).Compile()());//0
    View Code

    ParameterExpression 命名的参数表达式

    ParameterExpression param = Expression.Parameter(typeof(int));

    IndexExpression 编制属性或数组的索引

    1                 ParameterExpression arrayExpr = Expression.Parameter(typeof(int[]), "Array");
    2                 ParameterExpression indexExpr = Expression.Parameter(typeof(int), "Index");
    3                 ParameterExpression valueExpr = Expression.Parameter(typeof(int), "Value");
    4                 Expression arrayAccessExpr = Expression.ArrayAccess(
    5                     arrayExpr,
    6                     indexExpr
    7                 );//Array[Index]
    View Code

    InvocationExpression 将委托或 lambda 表达式应用于参数表达式列表的表达式

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

    LambdaExpression 描述一个 lambda 表达式。 这将捕获与 .NET 方法体类似的代码块

    1                 ParameterExpression paramExpr = Expression.Parameter(typeof(int), "arg");
    2                 LambdaExpression lambdaExpr = Expression.Lambda(Expression.Add(paramExpr,Expression.Constant(1)),new List<ParameterExpression>() { paramExpr });
    3                 Console.WriteLine(lambdaExpr);// arg => (arg +1)
    View Code

    ElementInit   表示 IEnumerable 集合的单个元素的初始值设定项

    ListInitExpression 表示包含集合初始值设定项的构造函数调用

    NewExpression 构造函数调用

     1                 string tree1 = "maple";
     2                 string tree2 = "oak";
     3 
     4                 MethodInfo addMethod = typeof(Dictionary<int, string>).GetMethod("Add");
     5 
     6                 // Create two ElementInit objects that represent the
     7                 // two key-value pairs to add to the Dictionary.
     8                 ElementInit elementInit1 =Expression.ElementInit(addMethod,Expression.Constant(tree1.Length),Expression.Constant(tree1));
     9                 ElementInit elementInit2 =Expression.ElementInit(addMethod,Expression.Constant(tree2.Length),Expression.Constant(tree2));
    10 
    11                 // Create a NewExpression that represents constructing
    12                 // a new instance of Dictionary<int, string>.
    13                 NewExpression newDictionaryExpression = Expression.New(typeof(Dictionary<int, string>));//等价 new Dictionary<int, string>();
    14                 
    15                 // Create a ListInitExpression that represents initializing
    16                 // a new Dictionary<> instance with two key-value pairs.
    17                 ListInitExpression listInitExpression = Expression.ListInit(newDictionaryExpression, elementInit1, elementInit2);//等价 var dic= new Dictionary<int, string>{}; dic.Add(5,"maple");dic.Add(3,"oak");
    18                 
    19                 Console.WriteLine(listInitExpression.ToString());
    View Code

    LoopExpression 无限循环。 可以使用“break”退出它

    LabelTarget  表示 GotoExpression 的目标

     1                 ParameterExpression value = Expression.Parameter(typeof(int), "value");
     2                 ParameterExpression result = Expression.Parameter(typeof(int), "result");
     3                 LabelTarget label = Expression.Label(typeof(int));
     4                 BlockExpression block = Expression.Block(
     5                     new[] { result },
     6                     Expression.Assign(result, Expression.Constant(1)),
     7                         Expression.Loop(
     8                            Expression.IfThenElse(
     9                                Expression.GreaterThan(value, Expression.Constant(1)),
    10                                Expression.MultiplyAssign(result,
    11                                    Expression.PostDecrementAssign(value)),
    12                                Expression.Break(label, result)
    13                            ),
    14                        label
    15                     )
    16                 );
    17                 //var s =value=>
    18                 //{
    19                 //    var result = 1;
    20                 //    for (int i = value; i >1; i--)
    21                 //    {
    22                 //        result *= i;
    23                 //    }
    24                 //    return result;
    25                 //};
    View Code

    MemberAssignment 针对对象的字段或属性的赋值运算

    MemberBinding 提供一种基类,该基类派生表示绑定的类,这些绑定用于初始化新创建对象的成员

    MemberExpression 访问字段或属性

    MemberInitExpression 调用构造函数并初始化新对象的一个或多个成员

    MemberListBinding 初始化新创建对象的集合成员的元素

    MemberMemberBinding 初始化新创建对象的成员的成员

     1     public class BaseEntity
     2     {
     3         /// <summary>
     4         /// 创建人账号
     5         /// </summary>    
     6         [DataMember]
     7         [Display(Name = "创建人账号")]
     8         [Column]
     9         public string CreateMan { get; set; }
    10         /// <summary>
    11         /// 创建时间
    12         /// </summary>    
    13         [DataMember]
    14         [Display(Name = "创建时间")]
    15         public DateTime CreateDateTime { get; set; }
    16         /// <summary>
    17         /// 异动人账号
    18         /// </summary>    
    19         [DataMember]
    20         [Display(Name = "异动人账号")]
    21         public string TrMan { get; set; }
    22         /// <summary>
    23         /// 异动时间
    24         /// </summary>    
    25         [DataMember]
    26         [Display(Name = "异动时间")]
    27         public DateTime TrDateTime { get; set; }
    28         /// <summary>
    29         /// 时间戳
    30         /// </summary>    
    31         [DataMember]
    32         [Display(Name = "时间戳")]
    33         public DateTime? TrVersion { get; set; }
    34     }
    View Code
     1                 BaseEntity entity = new BaseEntity();
     2                 NewExpression newExp = Expression.New(typeof(BaseEntity));
     3 
     4                 MemberInfo createMan = typeof(BaseEntity).GetMember("CreateMan")[0];
     5                 MemberInfo trMan = typeof(BaseEntity).GetMember("TrMan")[0];
     6                 MemberBinding createManMemberBinding = Expression.Bind(createMan, Expression.Constant("horse"));
     7                 MemberBinding trManMemberBinding = Expression.Bind(trMan, Expression.Constant("admin"));
     8                 MemberInitExpression memberInitExpression = Expression.MemberInit(newExp, createManMemberBinding, trManMemberBinding);
     9 
    10                 Console.WriteLine(memberInitExpression.ToString());
    View Code

    NewArrayExpression 创建新数组并可能初始化该新数组的元素

     1                 List<Expression> trees =new List<Expression>()
     2                 { 
     3                     Expression.Constant("oak"),
     4                     Expression.Constant("fir"),
     5                     Expression.Constant("spruce"),
     6                     Expression.Constant("alder") 
     7                 };
     8                 NewArrayExpression newArrayExpression =Expression.NewArrayInit(typeof(string), trees);
     9                 
    10                 // new [] {"oak", "fir", "spruce", "alder"}
    11                 Console.WriteLine(newArrayExpression.ToString());
    View Code

    SwitchCase  SwitchExpression 的一个事例

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

    1                 ConstantExpression switchValue = Expression.Constant(2);
    2                 SwitchExpression switchExpr =Expression.Switch(switchValue,new SwitchCase[] {
    3                     Expression.SwitchCase(Expression.Call(null,
    4                     typeof(Console).GetMethod("WriteLine", new Type[] { typeof(String) }),
    5                     Expression.Constant("First")),Expression.Constant(1)),
    6                     Expression.SwitchCase(Expression.Call(null,
    7                     typeof(Console).GetMethod("WriteLine", new Type[] { typeof(String) }),
    8                     Expression.Constant("Second")),Expression.Constant(2))});
    9                 Expression.Lambda<Action>(switchExpr).Compile()();
    View Code

    TryExpression  try/catch/finally/fault 块

    CatchBlock  try 块中的 catch 语句

    1                     TryExpression tryCatchExpr =Expression.TryCatch(
    2                     Expression.Block(
    3                         Expression.Throw(Expression.Constant(new DivideByZeroException())),
    4                         Expression.Constant("Try block")
    5                     ),
    6                     Expression.Catch(
    7                         typeof(DivideByZeroException),
    8                         Expression.Constant("Catch block") 
    9                 ));
    View Code

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

    UnaryExpression typeAsExpression =Expression.TypeAs(Expression.Constant(34, typeof(int)),typeof(int?));//等价    34 as int?;

    微软文档地址:

    System.Linq.Expressions:https://docs.microsoft.com/zh-cn/dotnet/api/system.linq.expressions?view=netframework-4.8

    ExpressionType:https://docs.microsoft.com/zh-cn/dotnet/api/system.linq.expressions.expressiontype?view=netframework-4.8#System_Linq_Expressions_ExpressionType_Add

  • 相关阅读:
    java并发编程——Excutor
    java并发编程——BlockingQueue
    const int *p和int * const p的区别(常量指针与指向常量的指针)
    C语言 enum作为函数返回值及函数参数
    (void)0;
    浅析IAR环境下Flash loader工作原理 (转)
    xilinx zcu106 vcu demo
    flashloader速度提升
    typora--简洁的markdown编辑器
    vivado 2019.2 工程修改文件夹名称后引起的一系列问题
  • 原文地址:https://www.cnblogs.com/Dewumu/p/11760686.html
Copyright © 2020-2023  润新知