Expression 表达式树学习整理

整理了一下表达式树的一些东西,入门足够了

先从ConstantExpression 开始一步一步的来吧  它表示具有常量值的表达式

我们选建一个控制台应用程序

            ConstantExpression _constExp = Expression.Constant("aaa",typeof(string));//一个常量
            //Console.Writeline("aaa");
            MethodCallExpression _methodCallexp=Expression.Call(typeof(Console).GetMethod("WriteLine",new Type[]{typeof(string)}),_constExp);
            Expression<Action> consoleLambdaExp = Expression.Lambda<Action>(_methodCallexp);
            consoleLambdaExp.Compile()();

            Console.ReadLine();

下边的MethodCallExpression你也许不知道是什么回事,不要急我下边会详细讲的,这相当于

Console.WriteLine("aaa");  输出一个常量,看一下结果

如果想自己输入一个值输出呢,那就用ParameterExpression 它表示一个参数表达式,我们只要把上边的代码做一下小改动就行

            ParameterExpression _parameExp = Expression.Parameter(typeof(string), "MyParameter");

            MethodCallExpression _methodCallexpP = Expression.Call(typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }), _parameExp);
            Expression<Action<string>> _consStringExp = Expression.Lambda<Action<string>>(_methodCallexpP, _parameExp);
            _consStringExp.Compile()("Hello!!");

参数parameExp就是一个string类型的变量我们让它输出一个Hello!!

有点感觉了吧,慢慢来好玩的还在后边,现在我们就说一下MethodCallExpression它可以调用静态方法和实例方法,我们上边的代码就是调用 的静态方法

,我先讲一下调用静态方法,再讲调用实例方法。

我们建一个返回string的静态方法,传入一个object类型的值

        public static string ConsStr(object str)
        {
            string _str = str + "aa";
            Console.WriteLine(_str);
            return _str;
        }

看一下我们是怎么调用自己的静态方法的

            ParameterExpression _paraObj = Expression.Parameter(typeof(object), "objPara");
            MethodCallExpression _MyStateMethod = Expression.Call(typeof(Program).GetMethod("ConsStr", new Type[] { typeof(object) }), _paraObj);
            Expression<Func<object, string>> _meyLambdaState = Expression.Lambda<Func<object, string>>(_MyStateMethod, _paraObj);
            string s_tr = _meyLambdaState.Compile()("ni Hao");
            Console.WriteLine("返回值: " + s_tr);

new Type[] { typeof(object) } 就是我们的方法里的参数类型,后边的paraObj是相当于参数值了,如果 是多参数就在 Type[],和后边再加上相应 的类型和参数就行

静态方法你有些了解了,下面讲一下调用实例方法

我们写一个非静态方法

        public string ConsStr2(object str)
        {
            string _str = str + "aa";
            Console.WriteLine(_str);
            return _str;
        }

调用的时候只要把上边的代码改动一点就ok Expression.Call为我们提供了我们想要的重载

            Program _pg = new Program();
            ParameterExpression _paraObj2 = Expression.Parameter(typeof(object), "objPara");
            MethodCallExpression _MyStateMethod2 = Expression.Call(Expression.Constant(_pg), typeof(Program).GetMethod("ConsStr2"), _paraObj2);
            Expression<Func<object, string>> _meyLambdaState2 = Expression.Lambda<Func<object, string>>(_MyStateMethod2, _paraObj2);
            string s_tr2 = _meyLambdaState.Compile()("you shi ni ");
            Console.WriteLine("返回值: " + s_tr2);

 简单吧。

再下来我们讲什么呢,也许你猜到了UnaryExpression一元运算符表达式和 BinaryExpression  二元运算符表达式

我们先看一个这两个表达式的简单例子后,我们再做一个复杂的例子

UnaryExpression我们做一个5--的表达式

            ConstantExpression _consNum = Expression.Constant(5, typeof(int));
            UnaryExpression _unaryPlus = Expression.Decrement(_consNum);
            Expression<Func<int>> _unaryLam = Expression.Lambda<Func<int>>(_unaryPlus);
            Console.WriteLine(_unaryLam.Compile()());

BinaryExpression  我们做一个a+b的例子 

            ParameterExpression _ParaA = Expression.Parameter(typeof(int), "a");
            ParameterExpression _ParaB = Expression.Parameter(typeof(int), "b");
            BinaryExpression _BinaAdd = Expression.Add(_ParaA, _ParaB);
            Expression<Func<int, int, int>> _MyBinaryAddLamb = Expression.Lambda<Func<int, int, int>>(_BinaAdd, new ParameterExpression[] { _ParaA, _ParaB });
            Console.WriteLine("表达式:  "+ _MyBinaryAddLamb);
            Console.WriteLine(_MyBinaryAddLamb.Compile()(3, 6));

不难吧,

我们做一把两个表达式放一起做一个例子吧 (a+b)*(--c)

            ParameterExpression _ParaA = Expression.Parameter(typeof(int), "a");
            ParameterExpression _ParaB = Expression.Parameter(typeof(int), "b");
            BinaryExpression _BinaAdd = Expression.Add(_ParaA, _ParaB);  //a+b

            ParameterExpression _paraC = Expression.Parameter(typeof(int), "c");
            UnaryExpression _paraDecr = Expression.Decrement(_paraC);    //(a+b)*(--c)
            BinaryExpression _binaMultiply = Expression.Multiply(_BinaAdd, _paraDecr);
            Expression<Func<int, int, int, int>> _MyBinaryLamb = Expression.Lambda<Func<int, int, int, int>>(_binaMultiply, new ParameterExpression[] { _ParaA, _ParaB, _paraC });
            Console.WriteLine("表达式:  "+ _MyBinaryLamb);
            Console.WriteLine(_MyBinaryLamb.Compile()(3, 6, 5));

今天就讲到这

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏跟着阿笨一起玩NET

DataGridView绑定BindingList<T>带数据排序的类

本文章转载:http://yuyingying1986.blog.hexun.com/30905610_d.html

10310
来自专栏技术博客

编写高质量代码改善C#程序的157个建议[为类型输出格式化字符串、实现浅拷贝和深拷贝、用dynamic来优化反射]

  本文已更新至http://www.cnblogs.com/aehyok/p/3624579.html 。本文主要学习记录以下内容:

10930
来自专栏yl 成长笔记

c# 委托(Func、Action)

以前自己写委托都用 delegate, 最近看组里的大佬们都用 Func , 以及 Action 来实现, 代码简洁了不少, 但是看得我晕晕乎乎。 花点时间研究...

2.3K30
来自专栏GreenLeaves

C# 自定义类型通过实现IFormattable接口,来输出指定的格式和语言文化的字符串(例:DateTime)

在开发一些国际化的应用时,应用程序需要调用与当前线程不同的语言文化来格式化字符串.

14030
来自专栏林德熙的博客

win10 uwp unix timestamp 时间戳 转 DateTime

有时候需要把网络的 unix timestamp 转为 C# 的 DateTime ,在 UWP 可以如何转换?

7510
来自专栏码农分享

原型模式(Prototype)

原型模式的结构 原型模式包含以下3个角色: •Prototype(抽象原型类) •ConcretePrototype(具体原型类) •Client(客户...

12230
来自专栏码云1024

C#反射

32430
来自专栏跟着阿笨一起玩NET

嘿,原来不认识你,想不到你这么好用—说说.NET中被我忽视的方法

下面就说说被我忽视过的方法。当然,每个人的编程经历,涉猎面及对.NET的认知程度都不一样。所以,这只是一家之言,肯定有很多不足之处,欢迎大家批评指正。

8810
来自专栏用户3030674的专栏

Java中Json解析

首先准备一个JSON格式的字符串 * String JsonStr = "{object:{persons:" + "[{name:'呵呵',im...

44420
来自专栏技术博客

C#多线程

根据上一节中http://www.cnblogs.com/aehyok/archive/2013/05/02/3054615.html对多线程的入门了解。本节就...

10020

扫码关注云+社区

领取腾讯云代金券