开发者社区> zting科技> 正文

CodeDom系列-开篇HelloWord

简介:
+关注继续查看

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

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

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

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

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

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

还是先贴上代码:

 

复制代码
using System;
using System.Text;
using System.CodeDom;
using System.CodeDom.Compiler;

namespace CodeDomDemo1
{
    
class Program
    {
        
static void Main(string[] args)
        {
            Program pro 
= new Program();
            CodeNamespace nspace 
= pro.CreateCodeDomHelloDemo();
            Console.WriteLine(pro.GengerCode(nspace));
            
string filename = "HelloWorld.exe";
            CompilerResults result
= pro.Execute(nspace,filename);
            
if (result.Errors.HasErrors)//是否存在错误;
            {
                
for (int i = 0; i < result.Output.Count; i++)

                    Console.WriteLine(result.Output[i]);

                
for (int i = 0; i < result.Errors.Count; i++)

                    Console.WriteLine(i.ToString() 
+ "" + result.Errors[i].ToString());
            }
            
else
            {
                System.Diagnostics.Process.Start(filename);
//这里比较懒,不想动手去自己打开,呵呵;
            }
            Console.Read();
        }

        
public CodeNamespace CreateCodeDomHelloDemo()
        {
            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);//
            return nspace;
        }

        
public string GengerCode(CodeNamespace nspace)
        {
            StringBuilder sb 
= new StringBuilder();
            System.IO.StringWriter sw 
= new System.IO.StringWriter(sb);
            CodeGeneratorOptions geneOptions 
= new CodeGeneratorOptions();//代码生成选项

                geneOptions.BlankLinesBetweenMembers 
= false;

                geneOptions.BracingStyle 
= "C";

                geneOptions.ElseOnClosing 
= true;

                geneOptions.IndentString 
= "    ";
                CodeDomProvider.GetCompilerInfo(
"c#").CreateProvider().GenerateCodeFromNamespace(nspace, sw, geneOptions);//代码生成
                sw.Close();
                
return sb.ToString();

        }

        
public CompilerResults Execute(CodeNamespace nspace, string filename)
        {
            CodeCompileUnit unit
=new CodeCompileUnit();//code编译单元
            unit.Namespaces.Add(nspace);
           CodeDomProvider provider
=  CodeDomProvider.CreateProvider("C#");  
            CompilerParameters options
=new CompilerParameters();//
           
            options.GenerateInMemory 
=false;//是否在内存中生成;
             options.IncludeDebugInformation =true;// 包含调试信息;
            options.ReferencedAssemblies.Add("System.dll");
            options.OutputAssembly 
= filename;
            
if (System.IO.Path.GetExtension(filename).ToLower() == ".exe")
            {
                options.GenerateExecutable 
= true;//true为可执行exe,false:dll
            }
            
else
            {
                options.GenerateExecutable 
= false;//true为可执行exe,false:dll
            }
           
return  provider.CompileAssemblyFromDom(options, unit);//编译程序集
        }

    }
}
复制代码

 

 

结果截图:
1:生成的代码:
image

2:运行结果:

image 

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

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

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



本文转自破狼博客园博客,原文链接:http://www.cnblogs.com/whitewolf/archive/2010/06/19/1760708.html,如需转载请自行联系原作者

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
如何设置阿里云服务器安全组?阿里云安全组规则详细解说
阿里云安全组设置详细图文教程(收藏起来) 阿里云服务器安全组设置规则分享,阿里云服务器安全组如何放行端口设置教程。阿里云会要求客户设置安全组,如果不设置,阿里云会指定默认的安全组。那么,这个安全组是什么呢?顾名思义,就是为了服务器安全设置的。安全组其实就是一个虚拟的防火墙,可以让用户从端口、IP的维度来筛选对应服务器的访问者,从而形成一个云上的安全域。
18582 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
27727 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,大概有三种登录方式:
12968 0
阿里云服务器安全组设置内网互通的方法
虽然0.0.0.0/0使用非常方便,但是发现很多同学使用它来做内网互通,这是有安全风险的,实例有可能会在经典网络被内网IP访问到。下面介绍一下四种安全的内网互联设置方法。 购买前请先:领取阿里云幸运券,有很多优惠,可到下文中领取。
21935 0
阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
阿里云服务器Windows系统默认用户名administrator,Linux镜像服务器用户名root
15292 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
19980 0
腾讯云服务器 设置ngxin + fastdfs +tomcat 开机自启动
在tomcat中新建一个可以启动的 .sh 脚本文件 /usr/local/tomcat7/bin/ export JAVA_HOME=/usr/local/java/jdk7 export PATH=$JAVA_HOME/bin/:$PATH export CLASSPATH=.
14855 0
+关注
3550
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载