zoukankan      html  css  js  c++  java
  • 吐槽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的死去。

  • 相关阅读:
    第一个WPF
    redis pub/sub 发布订阅
    php中header函数后是否应该有exit
    redis的图形界面管理工具
    redis key和value数据类型
    螺旋式打印一个二维数组
    jquery 提示插件 cluetip
    php异常处理
    ruby Methods, Procs, Lambdas, and Closures
    ruby迭代器iterator和枚举器Enumerator
  • 原文地址:https://www.cnblogs.com/BillySir/p/5330154.html
Copyright © 2011-2022 走看看