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,如需转载请自行联系原作者

目录
相关文章
|
消息中间件 网络协议 物联网
MQTT常见问题之物联网设备端申请动态注册时MQTT服务不可用如何解决
MQTT(Message Queuing Telemetry Transport)是一个轻量级的、基于发布/订阅模式的消息协议,广泛用于物联网(IoT)中设备间的通信。以下是MQTT使用过程中可能遇到的一些常见问题及其答案的汇总:
(续集)记录2分钟破解知识星球验证弹窗
那我换个思路,反正网站简单,这次直接用替换的方式
1944 0
|
XML Java Linux
【Linux 第三方库】linux 交叉编译dbus,expat
【Linux 第三方库】linux 交叉编译dbus,expat
765 0
|
自然语言处理 数据库 C语言
【视频】入门实战:MiniOB 概述和环境搭建 | 学习笔记
快速学习【视频】入门实战:MiniOB 概述和环境搭建
【视频】入门实战:MiniOB 概述和环境搭建 | 学习笔记
|
4月前
|
C++ Windows
Windows10添加自定义右键菜单VS Code
本文介绍了如何在Windows 10中通过修改注册表,将VS Code添加到右键菜单,实现右键文件、文件夹或空白处时使用VS Code打开。方法同样适用于其他程序,如Sublime Text 3。
|
弹性计算 Ubuntu Shell
用1C1G ECS搭建《阿里云大模型高级工程师ACP认证》学习环境
阿里云推出了《[阿里云大模型高级工程师ACP认证》,配套的学习资料较系统性的梳理了提示词、RAG、Agent插件、微调等系列LLM相关知识。推荐大家学习。 该学习课程需要搭建学习环境,可以直接在ECS上构建该环境即可,所需的资源很少,1C1G20G系统盘最低配置即可,本文介绍了详细搭建过程。
|
7月前
|
运维 数据挖掘 容器
埋点系统客户案例-金融媒体为何选择ClkLog替换10万年费的SaaS平台?
今天,我们继续为大家带来 ClkLog 用户回访系列,本期采访嘉宾是一家国内知名金融媒体平台的运维负责人——严老师。 这家金融媒体平台专注于全球财经新闻、市场动态和投资分析,提供涵盖股票、债券、外汇、大宗商品等领域的实时市场动态、深度分析、行业报告及专家观点。 他们曾使用业内知名的数据分析系统,但出于成本优化的考虑,开启了一轮新的产品选型。最终,ClkLog成功“打动”了他们,让我们一起来看看其中的关键因素。
268 60
埋点系统客户案例-金融媒体为何选择ClkLog替换10万年费的SaaS平台?
|
8月前
|
JSON 数据格式
基于 PAI-ArtLab 使用 ComfyUI 生成产品效果图
本文介绍了通过PAI ArtLab平台生成电商背景图的实验。用户可上传汽车、家电、化妆品等产品图片,快速生成背景并提升画质,实现降本增效。具体步骤包括登录阿里云完成实名认证,访问PAI ArtLab平台领取免费试用资源,使用ComfyUI加载工作流并上传图片,调整参数生成结果。此外,还提供了 Flux重绘和ControlNet微调等高级功能,以及常见问题解答,帮助用户更好地操作与优化图片效果。
|
机器学习/深度学习 数据采集 TensorFlow
使用Python实现智能物流路径优化
使用Python实现智能物流路径优化
432 1
|
弹性计算 运维 Shell
统计双色球各个数字的中奖概率
【4月更文挑战第29天】
561 1