吐槽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的死去。
博主简介:佘焕敏(shé),洋名 Billy Sir。
关注编程基础技术,并致力于研究软件的自动化生成。 对编程规范化、面向对象的极致使用也有着浓厚的兴趣。 同时非常希望能够写程序到65岁。
只有工匠精神,才能把常人觉得单调乏味的代码,当作作品雕刻成艺术品。
重点:这里几乎每一篇文章,都是我认真创作的,凝结了心血。写作从来都不是一件容易的事,对从小语文不好的我而言,是难上加难。而且,你发现没有,文中没有广告。这篇文章介绍了为什么要写这些文章。

【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性