干货表达式树解析框架1.docx
- 文档编号:8806465
- 上传时间:2023-02-01
- 格式:DOCX
- 页数:21
- 大小:47.95KB
干货表达式树解析框架1.docx
《干货表达式树解析框架1.docx》由会员分享,可在线阅读,更多相关《干货表达式树解析框架1.docx(21页珍藏版)》请在冰豆网上搜索。
干货表达式树解析框架1
关于我和表达式树
其实我也没有深入了解表达式树一些内在实现的原理,所以具体来说它到底是个什么东西我也不是很清楚,我的理解只是他是可以将'部分'委托构造成对象,方便我们对他进行解析;虽然我没有完全搞懂表达式树,但这并不妨碍我使用它(如果以后有时间,我想我会更深入的去和它接触一下)
Lamda+表达式树的性能瓶颈
对于Lamda表达式树我的感觉是又爱又恨
书写和阅读方面,无疑是非常成功的,他大大的减少了书写难度,增加了可读性
但另一方面,在程序的性能上又是如此的糟糕
来看下面一个栗子:
staticvoidMain()
{
Where1(u=>u.Name=="1");
Where2(u=>u.Name=="1");
}
publicstaticvoidWhere1(Expression
{
}
publicstaticvoidWhere2(Func
{
}
栗子中的 Where1 和 Where2 两个方法,唯一的不同,一个是委托,一个是表达式树
同样运行Where1和Where2一万次,Where2是0ms,Where1是57ms
也就是说从Func
这对于我这样一个追求性能的人来说,实在是有点难受!
到不至于不能接受,只有有点难受
但从另一方面我也在考虑,为什么像这样的lamda不能直接预编译成Expression呢?
期待微软的优化吧~
伪框架
为什么我的标题中的框架为带有引号?
因为我觉得这其实是一个伪框架
但他确实能帮助我们更好的解析Expression对象,或许应该把他称之为解决方案或是别的
不过~管他呢!
能用就行了
你应该了解的Expression
刚才说了虽然我也没有完全搞懂,但是有些东西还是应该知道的
比如:
∙以Expression作为基类的子类一共有多少个
∙他们分别是干什么的
第一个问题比较简单
1.现在在vs中敲下System.Linq.Expressions.Expression
2.然后按F1
3.如果顺利的话,你现在已经打开了"MSDN"
4.如果没有的话就手动点一下吧
5.然后滚动到屏幕最下面
好了这里看到的就是所有`public`的子类(其实没有公开的还有更多)
至于他们分别是干什么用的,每一个都有自己不同的用法,这里不可能一一说明了,下面的内容也只会涉及到一部分,其他就要自己慢慢研究了
举个栗子:
BinaryExpression----表示包含二元运算符的表达式
最基础的用法就是它的三个属性Left,Right,NodeType
Left获取二元运算的左操作数。
www.ipb.cc
Right获取二元运算的右操作数。
NodeType获取此Expression的节点类型。
如it=it.Name=="blqw"就是一个BinaryExpression
Left=it.Name
Right="blqw"
NodeType=Equals
大概就是这么一个意思吧
效果预览
框架结构
嗯.允许我还是叫他框架吧,毕竟听上去比较高端大气上档次啊
暂时是这样
∙Parsers文件夹里面的是具体对应每一种表达式树的解析的具体实现
∙ExpressionParser 表达式树解析器抽象基类,实现IExpressionParser
∙ExpressionTypeCode 枚举,枚举了所有的类型的表达式树
∙IExpressionParser 表达式树解析器接口
∙Parser 调用解析器的静态对象,也可以看作入口或工厂,根据表达式树类型调用具体类
∙ParserArgs 解析器参数,在解析表达式树的方法中保持传递,可以保存解析中所使用的参数和保存解析结果
代码
publicclassParserArgs
{
publicParserArgs()
{
Builder=newStringBuilder();
}
publicStringBuilderBuilder{get;privateset;}
publicIList
publicreadonlystring[]FormsAlias={"it","A","B","C","D","E"};
}
ParserArgs
IExpressionParser
///
///
publicinterfaceIExpressionParser
{
voidSelect(Expressionexpr,ParserArgsargs);
voidWhere(Expressionexpr,ParserArgsargs);
voidGroupBy(Expressionexpr,ParserArgsargs);
voidHaving(Expressionexpr,ParserArgsargs);
voidOrderBy(Expressionexpr,ParserArgsargs);
voidObject(Expressionexpr,ParserArgsargs);
}
///
///
publicabstractclassExpressionParser
IExpressionParser
whereT:
Expression
{
publicabstractvoidSelect(Texpr,ParserArgsargs);
publicabstractvoidWhere(Texpr,ParserArgsargs);
publicabstractvoidGroupBy(Texpr,ParserArgsargs);
publicabstractvoidHaving(Texpr,ParserArgsargs);
publicabstractvoidOrderBy(Texpr,ParserArgsargs);
publicabstractvoidObject(Texpr,ParserArgsargs);
publicvoidSelect(Expressionexpr,ParserArgsargs)
{
Select((T)expr,args);
}
publicvoidWhere(Expressionexpr,ParserArgsargs)
{
Where((T)expr,args);
}
publicvoidGroupBy(Expressionexpr,ParserArgsargs)
{
GroupBy((T)expr,args);
}
publicvoidHaving(Expressionexpr,ParserArgsargs)
{
Having((T)expr,args);
}
publicvoidOrderBy(Expressionexpr,ParserArgsargs)
{
OrderBy((T)expr,args);
}
publicvoidObject(Expressionexpr,ParserArgsargs)
{
Object((T)expr,args);
}
}
ExpressionParser
///
///
publicenumExpressionTypeCode
{
///
///
Unknown=0,
///
///
Null=1,
///
///
BinaryExpression=2,
///
///
BlockExpression=3,
///
///
ConditionalExpression=4,
///
///
ConstantExpression=5,
///
这允许调试器在调试时突出显示正确的源代码。
///
DebugInfoExpression=6,
///
///
DefaultExpression=7,
///
///
DynamicExpression=8,
///
这包括return语句、break和continue语句以及其他跳转。
///
GotoExpression=9,
///
///
IndexExpression=10,
///
///
InvocationExpression=11,
///
///
LabelExpression=12,
///
这将捕获与.NET方法体类似的代码块。
///
LambdaExpression=13,
///
///
ListInitExpression=14,
///
可以使用“break”退出它。
///
LoopExpression=15,
///
///
MemberExpression=16,
///
///
MemberInitExpression=17,
///
///
MethodCallExpression=18,
///
///
NewArrayExpression=19,
///
///
NewExpression=20,
///
///
ParameterExpression=21,
///
///
RuntimeVariablesExpression=22,
///
///
SwitchExpression=23,
///
///
TryExpression=24,
///
///
TypeBinaryExpression=25,
///
///
UnaryExpression=26,
}
ExpressionTypeCode
///
///
publicstaticclassParser
{
privatestaticreadonlyIExpressionParser[]Parsers=InitParsers();
staticIExpressionParser[]InitParsers()
{
varcodes=Enum.GetValues(typeof(ExpressionTypeCode));
varparsers=newIExpressionParser[codes.Length];
foreach(ExpressionTypeCodecodeincodes)
{
if(code.ToString().EndsWith("Expression"))
{
vartype=Type.GetType(typeof(Parser).Namespace+"."+code.ToString()+"Parser");
if(type!
=null)
{
parsers[(int)code]=(IExpressionParser)Activator.CreateInstance(type);
}
}
}
returnparsers;
}
///
///
Expression
///
publicstaticExpressionTypeCodeGetCodeType(Expressionexpr)
{
if(expr==null)
{
returnExpressionTypeCode.Null;
}
if(exprisBinaryExpression)
{
returnExpressionTypeCode.BinaryExpression;
}
if(exprisBlockExpression)
{
returnExpressionTypeCode.BlockExpression;
}
if(exprisConditionalExpression)
{
returnExpressionTypeCode.ConditionalExpression;
}
if(exprisConstantExpression)
{
returnExpressionTypeCode.ConstantExpression;
}
if(exprisDebugInfoExpression)
{
returnExpressionTypeCode.DebugInfoExpression;
}
if(exprisDefaultExpression)
{
returnExpressionTypeCode.DefaultExpression;
}
if(exprisDynamicExpression)
{
returnExpressionTypeCode.DynamicExpression;
}
if(exprisGotoExpression)
{
returnExpressionTypeCode.GotoExpression;
}
if(exprisIndexExpression)
{
returnExpressionTypeCode.IndexExpression;
}
if(exprisInvocationExpression)
{
returnExpressionTypeCode.InvocationExpression;
}
if(exprisLabelExpression)
{
returnExpressionTypeCode.LabelExpression;
}
if(exprisLambdaExpression)
{
returnExpressionTypeCode.LambdaExpression;
}
if(exprisListInitExpression)
{
returnExpressionTypeCode.ListInitExpression;
}
if(exprisLoopExpression)
{
returnExpressionTypeCode.LoopExpression;
}
if(exprisMemberExpression)
{
returnExpressionTypeCode.MemberExpression;
}
if(exprisMemberInitExpression)
{
returnExpressionTypeCode.MemberInitExpression;
}
if(exprisMethodCallExpression)
{
returnExpressionTypeCode.MethodCallExpression;
}
if(exprisNewArrayExpression)
{
returnExpressionTypeCode.NewArrayExpression;
}
if(exprisNewExpression)
{
returnExpressionTypeCode.NewArrayExpression;
}
if(exprisParameterExpression)
{
returnExpressionTypeCode.ParameterExpression;
}
if(exprisRuntimeVariablesExpression)
{
returnExpressionTypeCode.RuntimeVariablesExpression;
}
if(exprisSwitchExpression)
{
returnExpressionTypeCode.SwitchExpression;
}
if(exprisTryExpression)
{
returnExpressionTypeCode.TryExpression;
}
if(exprisTypeBinaryExpression)
{
returnExpressionTypeCode.TypeBinaryExpression;
}
if(exprisUnaryExpression)
{
returnExpressionTypeCode.UnaryExpression;
}
returnExpressionTypeCode.Unknown;
}
///
///
Expression
///
publicstaticIExpressionParserGetParser(Expressionexpr)
{
varcodetype=GetCodeType(expr);
varparser=Parsers[(int)codetype];
if(parser==null)
{
switch(codetype)
{
caseExpressionTypeCode.Unknown:
thrownewArgumentException("未知的表达式类型","expr");
caseExpressionTypeCode.Null:
thrownewArgumentNullException("expr","表达式为空");
default:
thrownewNotImplementedException("尚未实现"+codetype+"的解析");
}
}
returnparser;
}
publicstaticvoidSelect(Expressionexpr,ParserArgsargs)
{
GetParser(expr).Select(expr,args);
}
publicstaticvoidWhere(Expressionexpr,ParserArgsargs)
{
GetParser(expr).Where(expr,args);
}
publicstaticvoidGroupBy(Expressionexpr,ParserArgsargs)
{
GetParser(expr).GroupBy(expr,args);
}
publicstaticvoidHaving(Expressionexpr,ParserArgsargs)
{
GetParser(expr).Having(expr,ar
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 干货 表达式 解析 框架