使用 CodeDOM

更新:2007 年 11 月

CodeDOM 提供了表示许多常见的源代码元素类型的类型。您可以设计一个生成源代码模型的程序,使用 CodeDOM 元素构成一个对象图。可以使用受支持的编程语言的 CodeDOM 代码生成器,将该对象图呈现为源代码。CodeDOM 也可以用于将源代码编译成二进制程序集。

CodeDOM 的一些一般用途包括:

  • 模板化代码生成:生成 ASP.NET、XML Web 服务客户端代理、代码向导、设计器或其他代码发出机制的代码。

  • 动态编译:支持以一种或多种语言进行代码编译。

生成 CodeDOM 图

System.CodeDom 命名空间提供表示源代码的逻辑结构(与语言语法无关)的类。

CodeDOM 图的结构

CodeDOM 图的结构类似于一个容器树。每个可编译的 CodeDOM 图的最顶部(即根位置)的容器都是 CodeCompileUnit。源代码模型的每个元素都必须通过图中 CodeObject 的属性链接到图中。

为 Hello World 示例程序生成源代码模型

以下演练提供了一个如何生成 CodeDOM 对象图的示例,该对象图表示一个简单的应用程序 Hello World 的代码。要获得此代码示例的完整源代码,请参见 System.CodeDom.Compiler.CodeDomProvider 主题。

创建编译单元

CodeDOM 定义一个名为 CodeCompileUnit 的对象,该对象可以引用对要编译的源代码进行建模的 CodeDOM 对象图。CodeCompileUnit 具有存储属性、命名空间和程序集的引用的属性。

CodeDomProvider 类中派生的 CodeDom 提供程序包含用于处理 CodeCompileUnit 所引用的对象图的方法。

要创建简单应用程序的对象图,必须汇编源代码模型并从 CodeCompileUnit 引用它。

您可以用本示例中示范的语法创建一个新的编译单元:

Dim compileUnit As New CodeCompileUnit()
CodeCompileUnit compileUnit = new CodeCompileUnit();

CodeSnippetCompileUnit 可以包含已经以目标语言表示的源代码段,但不能呈现为另一种语言。

定义命名空间

若要定义命名空间,请创建一个 CodeNamespace,并使用适当的构造函数或通过设置其 Name 属性为它赋予一个名称。

Dim samples As New CodeNamespace("Samples")
CodeNamespace samples = new CodeNamespace("Samples");

导入命名空间

若要将命名空间的导入指令添加到命名空间,请添加 CodeNamespaceImport,它指示要导入到 CodeNamespace.Imports 集合的命名空间。

下面的代码将 System 命名空间的导入指令添加到名为 samples 的 CodeNamespaceImports 集合:

samples.Imports.Add( New CodeNamespaceImport("System") )
samples.Imports.Add( new CodeNamespaceImport("System") );

将代码元素链接到对象图中

构成 CodeDOM 图的所有代码元素都必须通过元素间直接从图的根对象属性引用的一系列引用链接到 CodeCompileUnit(树的根元素)。将对象设置为容器对象的属性以便从容器对象建立引用。

下面的语句将 samplesCodeNamespace 添加到根位置 CodeCompileUnitNamespaces 集合属性。

compileUnit.Namespaces.Add( samples )
compileUnit.Namespaces.Add( samples );

定义类型

若要用 CodeDOM 声明类、结构、接口或枚举,请创建一个新的 CodeTypeDeclaration,并为它赋予一个名称。下面的示例通过用构造函数重载设置 Name 属性来说明这一点:

Dim class1 As New CodeTypeDeclaration("Class1")
CodeTypeDeclaration class1 = new CodeTypeDeclaration("Class1");

若要将类型添加到命名空间,请添加 CodeTypeDeclaration,它表示要添加到 CodeNamespaceTypes 集合的命名空间的类型。

下面的示例演示了如何将名为 class1 的类添加到名为 samples 的 CodeNamespace

samples.Types.Add(class1)
samples.Types.Add(class1);

将类成员添加到类

System.CodeDom 命名空间提供了多种可用来表示类成员的元素。每个类成员都可以添加到 CodeTypeDeclarationMembers 集合。

定义可执行程序的代码入口点方法

如果生成可执行程序的代码,必须指示程序的入口点,具体做法是创建一个 CodeEntryPointMethod 来表示应从哪个方法开始执行程序。

下面的示例演示如何定义入口点方法(该方法包含调用 System.Console.WriteLine 以打印“Hello World!”的 CodeMethodInvokeExpression):

Dim start As New CodeEntryPointMethod()
Dim cs1 As New CodeMethodInvokeExpression( _
    New CodeTypeReferenceExpression("System.Console"), _
    "WriteLine", _
    New CodePrimitiveExpression("Hello World!") )
start.Statements.Add(cs1)  
CodeEntryPointMethod start = new CodeEntryPointMethod();
CodeMethodInvokeExpression cs1 = new CodeMethodInvokeExpression( 
    new CodeTypeReferenceExpression("System.Console"), 
    "WriteLine", new CodePrimitiveExpression("Hello World!") );
start.Statements.Add(cs1);  

下面的语句将名为 Start 的入口点方法添加到 class1 的 Members 集合:

class1.Members.Add( start )
class1.Members.Add( start );

现在,名为 CompileUnit 的 CodeCompileUnit 包含简单的 Hello World 程序的 CodeDOM 图。有关从 CodeDOM 图生成和编译代码的信息,请参见生成源代码和在 CodeDOM 图中编译程序

关于生成 CodeDOM 图的更多信息

CodeDOM 支持许多常见的代码元素类型,这些代码元素出现在支持公共语言运行库的编程语言中。CodeDOM 不会为表示各种可能的编程语言功能而提供相应元素。不容易用 CodeDOM 元素表示的代码可以封装在 CodeSnippetExpressionCodeSnippetStatementCodeSnippetTypeMemberCodeSnippetCompileUnit 中。但是,CodeDOM 无法自动将代码段转换为其他语言。

有关每个 CodeDOM 类型的文档,请参见 System.CodeDom 命名空间的参考文档。

有关定位表示特定代码元素类型的 CodeDOM 元素的速查表,请参见 CodeDOM 快速参考