c# 表达式树实验

原创
2021/04/27 13:48
阅读数 44

Func<int, int, int> myfunc = (a, b) => a + b;
            Expression<Func<int, int, int>> expression = (a, b) => a * b;

            Console.WriteLine(myfunc(3, 4));
            //Console.WriteLine(expression(5, 6));//expression是变量,但此处当作方法
            //上面分别表示Func委托和表达式树,看上去很相似。对于委托我们能控制执行,但内部代码在程序运行中是无法得知的,而表达式树刚好相反,表达式树是一种数据结构,可以获取内部细节。
            //上面xpression中是使用Lambda为表达式树赋值,还可以:
            ParameterExpression parameterExpressionA = Expression.Parameter(typeof(int),"a");
            //expression.Parameter(typeof(int), "a");//什么意思???
             //public static ParameterExpression Expression.Parameter(Type pyte,string name); //创建一个Expresions.ParameterExpression节点,该节点可用于标识树中的参数或变量
            //返回值Expressions.ParameterExpression,其Expressions.Expression.NodeType属性等于Expressions.ExpressionType.Parameter,并且其Expressions.Expression.Type和Expressions.ParameterExpression.Name属性设置为指定值
            ParameterExpression parameterExpressionB = Expression.Parameter(typeof(int), "b");
            BinaryExpression binaryExpression = Expression.Add(parameterExpressionA, parameterExpressionB);
            //BinaryExpression包含二元运算符的表达式
            //public sealed class Expression<TDelegate>:LambdaExpression
            //以目录树的形式将强类型 lambda表达式 表示为数据结构
            //其中二个函数很有意思:
            //public TDelegate Compile();将表达式树描述的lambda表达式编译为可执行代码并生成表示该lambda表达式的委托
            //public TDelegate Compile(DebugInfoGernerator debugInfoGenerator)带调试信息生成器
            //Expression<Func<int, int, int>> expressionD = Expression.Lambda(binaryExpression, parameterExpressionA, parameterExpressionB); //如果没有泛型指定类型则显示转换错误
            Expression<Func<int, int, int>> expressionD = Expression.Lambda<Func<int, int, int>>(binaryExpression, parameterExpressionA, parameterExpressionB); 
            //也就是说最开始的Expression<Func<int,int,int>> expression = (a,b) => a + b;其实就是上面的expressionD
            //Expression类是一个抽象类,表示表达式目录树节点的类派生自该基类,它还包含用来创建各种节点类型的静态工厂方法。
            //Expression类有很多子类,比如LambdaExpression,BinaryExpression,ParameterExpression,ConstantExpression,ConditionExpression,GotoExpression,LabelExpression等
            //其中LambdaExpression类中:
            //public Expression Body{get;}获取Lambda表达式的主体
            //public string name{get;}获取Lambda表达式的名称
            //public overrid sealed ExpressionType NodeType{get;}返回此Expression的节点类型 注意这种语法格式:因为在父类Expression中public virtual ExpressionType NodeType{get;}
            //也就是说在C#中父类virtual一个方法或属性方法之后,在子类中对这个方法或属性方法可以override,再如果加上sealed则表示不允许修改了
            //public ReadOnlyCollection<ParameterExpression> Parameters{get;}获取Lambda表达式的参数
            //pulbic Type ReturnType{get;} 返回值类型
            //pubilc override sealed Type[get;}获取此Expression所表示的表达式的静态类型
            Console.WriteLine(expression.Body.ToString()); //(a * b)
            Console.WriteLine(expression.NodeType.ToString());//Lambda
            Console.WriteLine(parameterExpressionA.NodeType.ToString() + "----" + parameterExpressionA.Type.BaseType.ToString());//Parameter----System.ValueType

            //除了System.ValueType,是不是还有引用类型??
            //Expression<Func<int,int,RefClas>> rcexp = (a,b)=>{return new RefClas(a,b);}//无法将具有语句体的Lambda表达式转换为Lambda表达式树
            //Expression<Func<int,int,RefClas>> rcexp = 感觉是不是要定义一个int int到RefClas对象的操作才能变成Lambad表达式树??????? 
            //比如ExpressionType等于ExpressionType.Convert的表达式操作 Convert强制转换或转换运算,如(SampleType)obj;对于数值转换,超范围转换也不会引发异常。具体如何写代码???

            //Lambda方法和通过API创建方法,共二种创建表达式树
            //API方法:
            ParameterExpression numParameterExpression = Expression.Parameter(typeof(int), "num");
            ConstantExpression five = Expression.Constant(5, typeof(int));
            BinaryExpression numLessThanFive = Expression.LessThan(numParameterExpression, five);
            Expression<Func<int, bool>> lambda = Expression.Lambda<Func<int, bool>>(numLessThanFive, numParameterExpression);
            Console.WriteLine("lambda的内容:{0}", lambda.ToString());//lambda的内容:num => (num < 5)
            //表达式的编译
            var func = lambda.Compile();
            Console.WriteLine("lambda的运行结果=" + func(6));

展开阅读全文
加载中

作者的其它热门文章

打赏
0
0 收藏
分享
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部
返回顶部
顶部