用着.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的更多相关文章

  1. 【.net 深呼吸】细说CodeDom(8):分支与循环

    有人会问,为啥 CodeDom 不会生成 switch 语句,为啥没生成 while 语句之类.要注意,CodeDom只关心代码逻辑,而不是语法,语法是给写代码的人用的.如果用.net的“反编译”工具 ...

  2. 【.net 深呼吸】细说CodeDom(7):索引器

    在开始正题之前,先补充一点前面的内容. 在方法中,如果要引用方法参数,前面的示例中,老周使用的是 CodeVariableReferenceExpression 类,它用于引用变量,也适用于引用方法参 ...

  3. 【.net 深呼吸】细说CodeDom(6):方法参数

    本文老周就给大伙伴们介绍一下方法参数代码的生成. 在开始之前,先补充一下上一篇烂文的内容.在上一篇文章中,老周检讨了 MemberAttributes 枚举的用法,老周此前误以为该枚举不能进行按位操作 ...

  4. 【.net 深呼吸】细说CodeDom(5):类型成员

    前文中,老周已经厚着脸皮介绍了类型的声明,类型里面包含的自然就是类型成员了,故,顺着这个思路,今天咱们就了解一下如何向类型添加成员. 咱们都知道,常见的类型成员,比如字段.属性.方法.事件.表示代码成 ...

  5. 【.net 深呼吸】细说CodeDom(3):命名空间

    在上一篇文章中,老周介绍了表达式和语句,尽管老周没有把所有的内容都讲一遍,但相信大伙至少已经掌握基本用法.在本文中,咱们继续探讨 CodeDom 方面的奥秘,这一次咱们聊聊命名空间. 在开始之前,老周 ...

  6. 【.net 深呼吸】细说CodeDom(2):表达式、语句

    在上一篇文章中,老周厚着脸皮给大伙介绍了代码文档的基本结构,以及一些代码对象与CodeDom类型的对应关系. 在评论中老周看到有朋友提到了 Emit,那老周就顺便提一下.严格上说,Emit并不是针对代 ...

  7. 【.net 深呼吸】细说CodeDom(1):结构大观

    CodeDom 是啥东东?Html Dom听过吧,XML Dom听过吧.DOM一般可翻译为 文档对象模型,那 Code + DOM呢,自然是指代码文档模型了.如果你从来没接触过 CodeDom,你大概 ...

  8. Javascript模拟继承(赠送.net吐槽一段)

    首先吐槽一句,今年的就业形势很不乐观啊,特别是搞.net的(相对java),特特别是还没出校门没有正式工作经验的,找个实习很难,前些天接了个面试电话,上来就质疑我“你一个在校大学生怎么可能做了那么多项 ...

  9. 这台计算机上缺少此项目引用的 NuGet 程序包-缺少的文件是 ..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.0\build\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props

    异常处理汇总-开发工具  http://www.cnblogs.com/dunitian/p/4522988.html 协助开发里面总有几个是极简爱好者,但是呢删了不该删的就会影响项目开发,下面看下完 ...

随机推荐

  1. ARM的栈指令

    ARM的指令系统中关于栈指令的内容比较容易引起迷惑,这是因为准确描述一个栈的特点需要两个参数: 栈地址的增长方向:ARM将向高地址增长的栈称为递增栈(Descendent Stack),将向低地址增长 ...

  2. Thinking in Unity3D:基于物理着色(PBS)的材质系统

    关于<Thinking in Unity3D> 笔者在研究和使用Unity3D的过程中,获得了一些Unity3D方面的信息,同时也感叹Unity3D设计之精妙.不得不说,笔者最近几年的引擎 ...

  3. magic方法的magic

    事实上,在python中一个类被实例化的时候首先被调用的并不是__init__方法,而是__new__方法.只是new方法一般很少重写.new方法会有返回值传给init方法.因此,init方法不能够有 ...

  4. Python 学习之路 (一):基础

    数据类型和变量 整数 在Python3中,整数可以处理任意大小的整数,不分长整型和整型, 十六进制用0x开头或者H结尾表示:0x2af ,2afH 用函数 int() 来转换字符串中的数字,里面不能包 ...

  5. Yii2的深入学习--行为Behavior

    我们先来看下行为在 Yii2 中的使用,如下内容摘自 Yii2中文文档 行为是 [[yii\base\Behavior]] 或其子类的实例.行为,也称为 mixins,可以无须改变类继承关系即可增强一 ...

  6. web前端性能调优

    最近2个月一直在做手机端和电视端开发,开发的过程遇到过各种坑.弄到快元旦了,终于把上线了.2个月干下来满满的的辛苦,没有那么忙了自己准备把前端的性能调优总结以下,以方便以后自己再次使用到的时候得于得心 ...

  7. React.js深入学习详细解析

    今天,继续深入学习react.js. 目录: 一.JSX介绍 二.React组件生命周期详解 三.属性.状态的含义和用法 四.React中事件的用法 五.组件的协同使用 六.React中的双向绑定   ...

  8. 移动端web开发的那些坑

    1.为非a列表项添加触感样式 通过js注册touchstart和touchend事件,添加触感class的方式, 有个坑,低版本的Android浏览器,经常触发不到touchend,需要再额外注册一个 ...

  9. xDebug + webgrind 对 php 程序进行性能分析

    环境 macOs Sierra php 7.0.8 MAMP Pro 集成环境 背景 最近有一个需要在微信朋友圈上线的 h5,本人做了一个抽奖的接口,也没多想,直接上 php ci(CodeIgnit ...

  10. 嵌入式开发中常见3个的C语言技巧

    Hey,大家好!我是CrazyCatJack.今天我来说几个在嵌入式开发中常用的C语言技巧吧.也许你曾经用过,也许你只是见到过但是没有深入理解.那么今天好好补充下吧^_^ 1.指向函数的指针 指针不光 ...