吐槽CodeDom
用着.NET Framework,发现了CodeDom的先天性缺陷,心里百般难受。
不知道 CodeDom 是什么的请看这里 CodeDom_百度百科
这里有CodeDom非常全的中文教程 CodeDOM - 随笔分类 - lichdr - 博客园
首先说,CodeDom的思想非常好,把代码当作研究的对象,用对象来表示代码,这为代码的动态处理提供了方便的可能。
CodeDom 的类型非常多,非常难以记得,经常凭着感觉组装CodeDom,却往往在几个很类似的类的选取时被迷惑了,特别是CodeTypeReference和CodeTypeReferenceExpression,还有很特别的CodeExpressionStatement。单看MSDN的注释非常抽象,幸好有勤劳的朋友作了整理。微软CodeDom模型学习笔记(全) - 赛提斯特 - 博客园
本次是我第N次接触CodeDom,我深知CodeDom写起来非常繁琐,所以本次我作了简单的封装,于是用起来简洁多了。
//创建一个对象
var NewDbContext = Code.Var("MyDbContext", "db", Code.New("MyDbContext")).Value;
var NewUser = Code.Var("User", "newUser", Code.New("User")).Value;
//调用一个方法
//db.Users.Add(newUser);
var db_Users_Add = Code.Var("db").Property("Users").Method("Add", Code.Var("newUser")).Value;
//db.SaveChanges();
var db_SaveChanges = Code.Var("db").Method("SaveChanges");
//if(!db.SaveChanges(...)){ ... } else { ... }
var If = Code.If(db_SaveChanges.Not())
.Then(Code.Class("Console").Method("WriteLine", Code.ConstValue("Register failed.")).AsStatement())
.Else(Code.Class("Console").Method("WriteLine", Code.ConstValue("Register Success.")).AsStatement())
.Value;
var codes = new CodeStatementCollection();
codes.Add(NewDbContext);
codes.Add(NewUser);
codes.Add(db_Users_Add);
codes.Add(If);
而在以前是这样写的:
CodeMemberMethod method = new CodeMemberMethod();//方法声明;
method.Name = "SayHello";// 方法名
method.Attributes = MemberAttributes.Public| MemberAttributes.Final;//属性
method.ReturnType = new CodeTypeReference(typeof(string));//返回类型
method.Statements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression("Hello from code!")));//方法体,只有一句返回语句return "Hello from code!"; CodeEntryPointMethod main = new CodeEntryPointMethod();//主方法Main
main.Statements.Add(new CodeVariableDeclarationStatement("HelloWord","hw",
new CodeObjectCreateExpression("HelloWord", new CodeExpression[] { })));//变量声明:HelloWord hw = new HelloWord(); CodeMethodInvokeExpression methodinvoke= new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("hw"),"SayHello",new CodeExpression[]{});
main.Statements.Add(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("System.Console"),"WriteLine", methodinvoke));
main.Statements.Add(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("System.Console"), "Read"));//两个方法调用:System.Console.WriteLine(hw.SayHello()); CodeTypeDeclaration helloword = new CodeTypeDeclaration("HelloWord");//类型Class声明
helloword.Attributes = MemberAttributes.Public;
helloword.Members.AddRange(new CodeTypeMember[]{method,main});//添加方法到clss CodeNamespace nspace = new CodeNamespace("HelloDemo1");//命名空间声明
nspace.Imports.Add(new CodeNamespaceImport("System"));//引入程序命名空间:using System;
nspace.Types.Add(helloword);
内容不对应,这里只是为了说明有封装和没封装的区别有多大。
可惜,一些“小”问题要找答案要找很久,要命的是,最终没有答案、/抓狂。最近就遇到了一个最简单的小到不能再小的问题,如何表示“逻辑非”运算,没错,就是C#中的感叹号(!),找了老半天,还请了高人朋友帮找,没有。也许有人说Snippets就可以,但如果在这样的一个封装中:输入一个Expression,把它包一层“非”成为新的Expression返回,Snippets也只能哭着说臣妾做不到啊。
看看这个 动态生成与编译(九)----CodeDOM的局限 - lichdr - 博客园 局限性还是不少的。
最重要重要的一点,CSharpCodeProvider.Parse没有实现,所有语言的Parse方法都没有实现,可恶的Microsoft,竟然不提供解析器!试验了所有的codeProvider,结果都是一样,这绝对是微软故意搞的,
想起几次研究项目都停止了,现在想想每次都是止于CodeDom,原来根源在此。所以,我将目光投向了NRefacotry,据文档说它非常强大。感谢 赛提斯特 的文章指引了这个好东西,不说了。我要去学习NRefacotry了。这玩意都是英文的,难啃啊。再次鄙视一下微软的CodeDom,不好好做,做到一半,不完整,破灭了它在我心中的美好形象。
此文纪念我心中美好的System.CodeDom的死去。
吐槽CodeDom的更多相关文章
- 【.net 深呼吸】细说CodeDom(8):分支与循环
有人会问,为啥 CodeDom 不会生成 switch 语句,为啥没生成 while 语句之类.要注意,CodeDom只关心代码逻辑,而不是语法,语法是给写代码的人用的.如果用.net的“反编译”工具 ...
- 【.net 深呼吸】细说CodeDom(7):索引器
在开始正题之前,先补充一点前面的内容. 在方法中,如果要引用方法参数,前面的示例中,老周使用的是 CodeVariableReferenceExpression 类,它用于引用变量,也适用于引用方法参 ...
- 【.net 深呼吸】细说CodeDom(6):方法参数
本文老周就给大伙伴们介绍一下方法参数代码的生成. 在开始之前,先补充一下上一篇烂文的内容.在上一篇文章中,老周检讨了 MemberAttributes 枚举的用法,老周此前误以为该枚举不能进行按位操作 ...
- 【.net 深呼吸】细说CodeDom(5):类型成员
前文中,老周已经厚着脸皮介绍了类型的声明,类型里面包含的自然就是类型成员了,故,顺着这个思路,今天咱们就了解一下如何向类型添加成员. 咱们都知道,常见的类型成员,比如字段.属性.方法.事件.表示代码成 ...
- 【.net 深呼吸】细说CodeDom(3):命名空间
在上一篇文章中,老周介绍了表达式和语句,尽管老周没有把所有的内容都讲一遍,但相信大伙至少已经掌握基本用法.在本文中,咱们继续探讨 CodeDom 方面的奥秘,这一次咱们聊聊命名空间. 在开始之前,老周 ...
- 【.net 深呼吸】细说CodeDom(2):表达式、语句
在上一篇文章中,老周厚着脸皮给大伙介绍了代码文档的基本结构,以及一些代码对象与CodeDom类型的对应关系. 在评论中老周看到有朋友提到了 Emit,那老周就顺便提一下.严格上说,Emit并不是针对代 ...
- 【.net 深呼吸】细说CodeDom(1):结构大观
CodeDom 是啥东东?Html Dom听过吧,XML Dom听过吧.DOM一般可翻译为 文档对象模型,那 Code + DOM呢,自然是指代码文档模型了.如果你从来没接触过 CodeDom,你大概 ...
- Javascript模拟继承(赠送.net吐槽一段)
首先吐槽一句,今年的就业形势很不乐观啊,特别是搞.net的(相对java),特特别是还没出校门没有正式工作经验的,找个实习很难,前些天接了个面试电话,上来就质疑我“你一个在校大学生怎么可能做了那么多项 ...
- 这台计算机上缺少此项目引用的 NuGet 程序包-缺少的文件是 ..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props
异常处理汇总-开发工具 http://www.cnblogs.com/dunitian/p/4522988.html 协助开发里面总有几个是极简爱好者,但是呢删了不该删的就会影响项目开发,下面看下完 ...
随机推荐
- MapReduce剖析笔记之四:TaskTracker通过心跳机制获取任务的流程
上一节分析到了JobTracker把作业从队列里取出来并进行了初始化,所谓的初始化,主要是获取了Map.Reduce任务的数量,并统计了哪些DataNode所在的服务器可以处理哪些Split等等,将这 ...
- JDBC基础
今天看了看JDBC(Java DataBase Connectivity)总结一下 关于JDBC 加载JDBC驱动 建立数据库连接 创建一个Statement或者PreparedStatement 获 ...
- Linux基礎知識 —— open&close
下面說一下在用戶空間調用open/close/dup跟驅動中的open和release的對應. 下面是測試驅動: #include <linux/module.h> #include &l ...
- 读书笔记--SQL必知必会19--存储过程
不同的DBMS对存储过程的实现不同,差异巨大,这里不涉及具体的DBMS,仅仅说明存储过程的简单含义. 19.1 存储过程 简单来说,存储过程就是为以后使用而保存的一条或多条SQL语句. 可以将存储过程 ...
- 前端CSS部分知识整理
1.如何清除图片下方出现几像素的空白间隙? /*方法1:*/ img{display:block;} 方法2: /*img{vertical-align:top;}*/ 2.如何让文本垂直对齐文本输入 ...
- git 版本回退
由于操作失误,需要将代码进行版本回退,首先在本地仓库执行了“git reset --hard HEAD^”命令,这样只会回退本地仓库的代码,但是我的代码之前已经push到了远程库中,查看远程仓库,发现 ...
- javascript编程杂记
1.数组深复制 var obj =[1,2,4]: var obj2 = obj.slice(0);
- ChatSecure
ChatSecure是一个免费和开源消息传递应用程序的特性 OTR加密在 XMPP. 你可以连接到现有的谷歌帐户或创建新帐户 公共XMPP服务器(包括通过 Tor),甚至 连接到您自己的服务器额外的安 ...
- 导出BOM表
1.Report->Bill of Materials for Project 将Value拖上左上角的Grouped Columns 2.在Excel表中全选器件,右键设置"设置单元 ...
- asp.net DataTable导出Excel 自定义列名
1.添加引用NPOI.dll 2.cs文件头部添加 using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using System.IO; 3.代码如 ...