程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 吐槽CodeDom,codedom

吐槽CodeDom,codedom

編輯:C#入門知識

吐槽CodeDom,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的死去。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved