博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(转)Expression Tree不完全入门
阅读量:5277 次
发布时间:2019-06-14

本文共 4073 字,大约阅读时间需要 13 分钟。

在.NET Framework 3.5中提供了表达式目录树(Expression Tree),它是一种抽象语法树或者说它是一种数据结构。在了解他之前我们需要从委托说起,

在.NET中委托是使用delegate 关键字声明的一个引用类型,类似于 C++ 中的函数指针,你可以把委托理解为方法的别名,只不过他代表了一类的方法。
委托是类型安全和可靠的。

1.我们举一个例子来简单说明委托的使用,假设我们有一个人员组织库,我们要列出库中所有人员的名字,下面是代码:

public class Employe    {        public string Name { get; set; }        public int Age { get; set; }        public Employe(string name,int age)        {            this.Name = name;            this.Age = age;        }    }
public delegate void ProcessEmployeDelegate(Employe emp);    public class EmpDataBase{        List
list = new List
{ new Employe("Cary",25), new Employe("James",34) }; public void ProcessEmploye(ProcessEmployeDelegate processEmploye) { foreach (Employe emp in list) { processEmploye(emp); } }}

 

class Program{                static void ShowEmpName(Employe emp)        {                        "名字:{0}".FormatWriteLine(emp.Name);        }             static void Main()        {                        EmpDataBase empdb = new EmpDataBase();            empdb.ProcessEmploye(ShowEmpName);         }

}

下面是结果:

名字:Cary

名字:James

上面我为String加了一个简单的扩展方法,代码如下:

public static void FormatWriteLine(this string format, params object[] args){     Console.WriteLine(string.Format(format, args));}
2.到.NET2.0时代,引入了匿名方法,使用匿名方法我们就不必创建单独的方法,而是将匿名方法直接作为参数传递。于是上面的主程序就可以改变为如下代码:
class Program{               static void Main()        {                        EmpDataBase empdb = new EmpDataBase();            empdb.ProcessEmploye(delegate(Employe emp)            {                "名字:{0}".FormatWriteLine(emp.Name);            });         } }
3.进入.NET3.X时代,我们又有了Lambda表达,可以将delegate关键字也去掉,让人彻底的看不见委托的影子,代码如下:
class Program{                static void Main()        {                        EmpDataBase empdb = new EmpDataBase();            empdb.ProcessEmploye(emp=>"名字:{0}".FormatWriteLine(emp.Name));         } }
4.到此为止我们的主程序是不是简化了许多。不过我们还声明了一个ProcessEmployeDelegate委托,我们可以使用Action
或Func来代替,Action
和Func
的功能没有什么区别,只是Action
没有返类型。代码如下:
public void ProcessEmploye(Action
processEmploye){ foreach (Employe emp in list) { processEmploye(emp); }}

 

5.了解了lambda表达式,其对应的具体语法树就是Expression Tree,其对应的相关API都在System.Linq.Expressions命名空间下,如下图:

http://images.cnblogs.com/cnblogs_com/carysun/WindowsLiveWriter/Expression_8A94/image_2.png

我们来看下Expression类的结构,该类有四个属性:

  Body:获取表达式的主体;

  Parameters:获取Lambda表达示的参数;
  NodeType:得到树中某些节点的表达式类型(ExpressionType),这是一个有45种不同值的枚举类型,代表表达式节点的所有可能类型,如返回常数、
                         也可能返回参数、或者返回一个值是否小于另外一个(<),或者返回一个值是否大于另外一个(>),或者返回两个值的和( )等等。
  Type:得到表达式的静态类型,在本例中,表达式的类型是Func。

6.我们构建,遍历,修改表达式目录树,还可以执行表达式目录树,下面继续举几个例子来说明。找出下面字符串数字中以“C”开头的员工(x => x.StartsWith("C")):

String[] names = new string[2] { "Cary","James"};Expression
> expression1 = (x) => x.StartsWith("C");"Expression is {0}\r\n".FormatWriteLine(expression1.ToString()); foreach (String name in names.Where(expression1.Compile())){ "{0 }".FormatWriteLine(name);}

 

7.找出人员库中年龄为25的员工,表达式为:Expression is age => (age.Age = 25)

ConstantExpression constEmpAge = Expression.Constant(25);ParameterExpression paramAge =Expression.Parameter(typeof(Employe), "age");MemberExpression mex =LambdaExpression.PropertyOrField(paramAge, "Age");BinaryExpression filter = Expression.Equal(mex, constEmpAge);Expression
> expression2 = Expression.Lambda
> (filter,new ParameterExpression[] { paramAge }); "Expression is {0}\r\n".FormatWriteLine(expression2.ToString());foreach (Employe emp in list.Where(expression2.Compile())){ "{0}:{1}".FormatWriteLine(emp.Name,emp.Age);}

 

8.我们还可以使用Expression Tree Visualizer来查看表达式目录树的相关信息,如下图:

http://images.cnblogs.com/cnblogs_com/carysun/WindowsLiveWriter/Expression_8A94/image_thumb_1.png

Expression Tree Visualizer的使用将ExpressionTreeVisualizer中的.dll文件拷贝到..\Program Files\Microsoft Visual Studio 9.0\Common7\Packages\Debugger\Visualizers.中。

本文没有过多深入的内容,只是希望给大家带来一些对Expression的基本认识,希望本文能对您有用。

转载自:

谢谢浏览!

 

转载于:https://www.cnblogs.com/Music/archive/2011/07/26/expression-tree-02.html

你可能感兴趣的文章
JavaScript基础——使用运算符
查看>>
CentOS7安装CDH 第十三章:CDH资源池配置
查看>>
DMSLinq表达式框架实现(一)
查看>>
图论---图的m-点着色判定问题(回溯法--迭代式)
查看>>
如何使用HTML5创建在线精美简历
查看>>
poj 2187 Beauty Contest
查看>>
qsort函数用法
查看>>
angular脏值检测策略
查看>>
centos 7 安装vlc
查看>>
HPUX 配置zabbix开机自动启动
查看>>
纯CSS实现3D按钮效果
查看>>
上海云栖—人工智能-视觉计算专场预热
查看>>
【BZOJ 4151 The Cave】
查看>>
MySQL数据备份之mysqldump使用
查看>>
Jsoncpp学习二---读取Json格式的文本文件
查看>>
java推送数据到app--极光推送
查看>>
C#面试分享:单例模式
查看>>
hdu 2199 Can you solve this equation?
查看>>
P1083 借教室
查看>>
(四)工厂方法模式详解(另附简单工厂的死亡之路)
查看>>