CodeDom系列-开篇HelloWord

简介:

 最近在自己实践一个异常扑捉设计,在模块中我觉得该给用户提供的是代码生成工具,而不是怎么去做,再自己去写代码。现在代码模板生成的有很多

但我选择了用微软的CODEDOM技术来实现,由于比较熟悉,以及感觉我将只用在.NET平台是已经够强大了。最近也总想写点博客,但是不知道写些什么,所以就准备写个CODEDOM的系列。仅是开篇,就写个简单的HelloWord程序吧。

CODEDOM在.NET Framework SDK文档里是这么讲述的:

.NET Framework 中包含一个名为“代码文档对象模型”(CodeDOM) 的机制,该机制使编写源代码的程序的开发人员可以在运行时,根据表示所呈现代码的单一模型,用多种编程语言生成源代码。

为表示源代码,CodeDOM 元素相互链接以形成一个数据结构(称为 CodeDOM 图),它以某种源代码的结构为模型。

System.CodeDom 命名空间定义可以表示源代码的逻辑结构(与具体的编程语言无关)的类型。System.CodeDom.Compiler 命名空间定义从 CodeDOM 图生成源代码的类型,和在受支持的语言中管理源代码编译的类型。编译器供应商或开发人员可以扩展受支持语言的集合。

还是先贴上代码:

 
 
  1. using System;  
  2. using System.Text;  
  3. using System.CodeDom;  
  4. using System.CodeDom.Compiler;  
  5.  
  6. namespace CodeDomDemo1  
  7. {  
  8.     class Program  
  9.     {  
  10.         static void Main(string[] args)  
  11.         {  
  12.             Program pro = new Program();  
  13.             CodeNamespace nspace = pro.CreateCodeDomHelloDemo();  
  14.             Console.WriteLine(pro.GengerCode(nspace));  
  15.             string filename = "HelloWorld.exe";  
  16.             CompilerResults result= pro.Execute(nspace,filename);  
  17.             if (result.Errors.HasErrors)//是否存在错误;  
  18.             {  
  19.                 for (int i = 0; i < result.Output.Count; i++)  
  20.  
  21.                     Console.WriteLine(result.Output[i]);  
  22.  
  23.                 for (int i = 0; i < result.Errors.Count; i++)  
  24.  
  25.                     Console.WriteLine(i.ToString() + ": " + result.Errors[i].ToString());  
  26.             }  
  27.             else 
  28.             {  
  29.                 System.Diagnostics.Process.Start(filename);//这里比较懒,不想动手去自己打开,呵呵;  
  30.             }  
  31.             Console.Read();  
  32.         }  
  33.  
  34.         public CodeNamespace CreateCodeDomHelloDemo()  
  35.         {  
  36.             CodeMemberMethod method = new CodeMemberMethod();//方法声明;   
  37.             method.Name = "SayHello";//  方法名  
  38.             method.Attributes = MemberAttributes.Public| MemberAttributes.Final;//属性  
  39.             method.ReturnType = new CodeTypeReference(typeof(string));//返回类型  
  40.             method.Statements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression("Hello  from code!")));//方法体,只有一句返回语句return "Hello  from code!";  
  41.  
  42.             CodeEntryPointMethod main = new CodeEntryPointMethod();//主方法Main  
  43.             main.Statements.Add(new CodeVariableDeclarationStatement("HelloWord","hw",  
  44.                 new CodeObjectCreateExpression("HelloWord", new CodeExpression[] { })));//变量声明:HelloWord hw = new HelloWord();  
  45.  
  46.          CodeMethodInvokeExpression methodinvoke=   new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("hw"),"SayHello",new CodeExpression[]{});  
  47.             main.Statements.Add(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("System.Console"),"WriteLine", methodinvoke));  
  48.             main.Statements.Add(new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("System.Console"), "Read"));//两个方法调用:System.Console.WriteLine(hw.SayHello());  
  49.              
  50.             CodeTypeDeclaration helloword = new CodeTypeDeclaration("HelloWord");//类型Class声明  
  51.             helloword.Attributes = MemberAttributes.Public;  
  52.             helloword.Members.AddRange(new CodeTypeMember[]{method,main});//添加方法到clss  
  53.  
  54.             CodeNamespace nspace = new CodeNamespace("HelloDemo1");//命名空间声明  
  55.             nspace.Imports.Add(new CodeNamespaceImport("System"));//引入程序命名空间:using System;  
  56.             nspace.Types.Add(helloword);//  
  57.             return nspace;  
  58.         }  
  59.  
  60.         public string GengerCode(CodeNamespace nspace)  
  61.         {  
  62.             StringBuilder sb = new StringBuilder();  
  63.             System.IO.StringWriter sw = new System.IO.StringWriter(sb);  
  64.             CodeGeneratorOptions geneOptions = new CodeGeneratorOptions();//代码生成选项  
  65.  
  66.                 geneOptions.BlankLinesBetweenMembers = false;  
  67.  
  68.                 geneOptions.BracingStyle = "C";  
  69.  
  70.                 geneOptions.ElseOnClosing = true;  
  71.  
  72.                 geneOptions.IndentString = "    ";  
  73.                 CodeDomProvider.GetCompilerInfo("c#").CreateProvider().GenerateCodeFromNamespace(nspace, sw, geneOptions);//代码生成  
  74.                 sw.Close();  
  75.                 return sb.ToString();  
  76.  
  77.         }  
  78.  
  79.         public CompilerResults Execute(CodeNamespace nspace, string filename)  
  80.         {  
  81.             CodeCompileUnit unit=new CodeCompileUnit();//code编译单元  
  82.             unit.Namespaces.Add(nspace);  
  83.            CodeDomProvider provider=  CodeDomProvider.CreateProvider("C#");    
  84.             CompilerParameters options=new CompilerParameters();//  
  85.              
  86.             options.GenerateInMemory =false;//是否在内存中生成;  
  87.              options.IncludeDebugInformation =true;// 包含调试信息;  
  88.             options.ReferencedAssemblies.Add("System.dll");  
  89.             options.OutputAssembly = filename;  
  90.             if (System.IO.Path.GetExtension(filename).ToLower() == ".exe")  
  91.             {  
  92.                 options.GenerateExecutable = true;//true为可执行exe,false:dll  
  93.             }  
  94.             else 
  95.             {  
  96.                 options.GenerateExecutable = false;//true为可执行exe,false:dll  
  97.             }  
  98.            return  provider.CompileAssemblyFromDom(options, unit);//编译程序集  
  99.         }  
  100.  
  101.     }  
  102. }  

结果截图

1.生成的代码 

2:运行结果:

上面代码很简单,我特意也把注释写上了,所以不用一句一句的讲解了,哈哈。

CodeDom提供了很多操作,如定义类,还可以定义结构、枚举;类里面的方法、属性、字段及构造函数;定义Attribute;事件及委托;赋值、条件(if)、循环(for)语句;变量声明;异常处理语句;甚至还可以加注释以及块(#region #endregion)。除了分支选择switch、while,dowhile循环及break、continue没发现外,其他大多数东西都有,着已经足够了,程序三大结构,足以实现很多的代码生成了。

msdn CodeDom参考:http://msdn.microsoft.com/zh-cn/library/f1dfsbhc(VS.80).aspx







 本文转自 破狼 51CTO博客,原文链接:http://blog.51cto.com/whitewolfblog/834311,如需转载请自行联系原作者


相关文章
|
6月前
|
XML 测试技术 数据格式
如何使用 ABAP 代码解析 XML 文件试读版
如何使用 ABAP 代码解析 XML 文件试读版
57 0
如何使用 ABAP 代码解析 XML 文件试读版
|
9月前
|
Java
【JavaSE】Java基础语法(三十三):File 一文详解
1. File类概述和构造方法 File类介绍 它是文件和目录路径名的抽象表示 文件和目录是可以通过File封装成对象的 对于File而言,其封装的并不是一个真正存在的文件,仅仅是一个路径名而已.它可以是存在的,也
|
9月前
|
Java
【JavaSE】Java基础语法(十五):继承
1. 继承的实现 继承的概念 继承是面向对象三大特征之一,可以使得子类具有父类的属性和方法,还可以在子类中重新 定义,以及追加属性和方法 实现继承的格式 继承通过extends实现 格式:class 子类 extends 父类 { } 举例:class Dog extends Animal { }
|
8月前
|
SQL 前端开发 关系型数据库
TienChin 开篇-运行 RuoYiVue
下载完毕之后,这个项目当中存在一个 ruoyi-ui 这个是前端,只是放在了这个项目当中方便我们进行
57 0
|
9月前
|
存储 移动开发 Java
【JavaSE】Java基础语法(三十六):File & IO流
1. File java.io.File类是文件和目录路径名的抽象表示形式,主要用于文件和目录的创建、查找和删除等操作。
|
9月前
|
存储 算法 Java
【JavaSE】Java基础语法(十四):Static
概述 Java中的static是一个修饰符(也可称关键字),可以用于修饰变量、方法和代码块。 特点与应用 static修饰的成员具有以下特点: 被类的所有对象共享 是我们判断是否使用静态关键字的条件 随着类的加载而加载,优先于对象存在 对象需要类被加载后,才能创建 可以通过类名调用 也可以通过对象名调用
|
9月前
|
Java
【JavaSE】Java基础语法(二十五):异常
1. 异常 异常的概述 异常就是程序出现了不正常的情况
|
9月前
|
Java
【JavaSE】Java基础语法(十七)
1. final fianl关键字的作用 final代表最终的意思,可以修饰成员方法,成员变量,类 final修饰类、方法、变量的效果 fianl修饰类:该类不能被继承(不能有子类,但是可以有父类) final修饰方法:该方法不能被重写 final修饰变量:表明该变量是一个常量,不能再次赋值
|
安全 Java 开发工具
|
存储 缓存 弹性计算
Unity Entity Component System 理论知识总结
今天跟同学们分享一下我找到的关于ECS相关的理论知识文章,可能比较枯燥,如果想看实操的请看我下方写的一些案例解析。 Unity之浅析 Entity Component System (ECS) Unity 之 Pure版Entity Compon...
1940 0