吐槽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 协助开发里面总有几个是极简爱好者,但是呢删了不该删的就会影响项目开发,下面看下完 ...
随机推荐
- 简单事件机制Java实现
一个很简单方便的事件处理方法. 使用效果 事件发布者: //定义事件 public static EventTrans<String> AuthFailed = new EventTran ...
- JavaScript面向对象
理解对象 对象这个词如雷贯耳,同样出名的一句话:XXX语言中一切皆为对象! 对象究竟是什么?什么叫面向对象编程? 对象(object),台湾译作物件,是面向对象(Object Oriented)中的术 ...
- 使用xUnit,EF,Effort和ABP进行单元测试(C#)
返回总目录<一步一步使用ABP框架搭建正式项目系列教程> 本篇目录 介绍 创建测试项目 准备测试基类 创建第一个测试 测试异常 在测试中使用仓储 测试异步方法 小结 介绍 在这篇博客中,我 ...
- Docker之Compose服务编排
Compose是Docker的服务编排工具,主要用来构建基于Docker的复杂应用,Compose 通过一个配置文件来管理多个Docker容器,非常适合组合使用多个容器进行开发的场景. 说明:Comp ...
- windows下获取IP地址的两种方法
windows下获取IP地址的两种方法: 一种可以获取IPv4和IPv6,但是需要WSAStartup: 一种只能取到IPv4,但是不需要WSAStartup: 如下: 方法一:(可以获取IPv4和I ...
- jQuery之常用且重要方法梳理(siblings,nextAll,end,wrap,apply,call,each)-(二)
1.siblings() siblings() 获得匹配集合中每个元素的同胞,通过选择器进行筛选是可选的. <body> <div><span>Hello</ ...
- 从零开始编写自己的C#框架(1)——前言
记得十五年前自学编程时,拿着C语言厚厚的书,想要上机都不知道要用什么编译器来执行书中的例子.十二年前在大学自学ASP时,由于身边没有一位同学和朋友学习这种语言,也只能整天混在图收馆里拼命的啃书.而再后 ...
- jeffy-vim-v3.0
jeffy-vim-v3.0 修改了配色.
- GDB调试命令
1.查看源码: list [函数名][行数] 2.暂停程序 (1)设置断点: a.break + [源代码行号][源代码函数名][内存地址] b.break ... if condition .. ...
- CentOS7 Jenkins安装
CentOS7 Jenkins安装 CentOS7 Jenkins安装 Download 从Jenkins下载apache-tomcat-8.0.18.tar.gz Install 安装 上传RPM文 ...