使用 CodeDOM

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 将其引用 。

可使用下例所示的语法来创建新的编译单元:

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

CodeSnippetCompileUnit 可以包含目标语言中已经存在的一部分源代码,但无法呈现为另一语言。

定义一个命名空间

若要定义命名空间,请创建 CodeNamespace,并使用适当的构造函数或设置其 Name 属性来为其分配名称 。

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

导入命名空间

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

下列代码添加导入,用于将 System 命名空间导入名为 samples 的 CodeNamespace 的 Imports 集合中 :

samples->Imports->Add(gcnew CodeNamespaceImport("System"));
samples.Imports.Add(new CodeNamespaceImport("System"));
samples.Imports.Add(new CodeNamespaceImport("System"))

形成 CodeDOM 图的所有代码元素都必须链接至作为树的根元素的 CodeCompileUnit,方法是通过一系列直接引用自该图根对象属性的元素之间的引用。 将对象设置为容器对象的属性,以建立来自容器对象的引用。

下列语句将 samples CodeNamespace 添加至根 CodeCompileUnit 的 Namespaces 集合属性。

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

定义一个类型

若要使用 CodeDOM 声明类、结构、接口或枚举,请创建新的 CodeTypeDeclaration,然后为其分配名称。 下列示例使用构造函数重载来设置 Name 属性对此进行了演示 :

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

若要向命名空间添加类型,请将代表要添加到命名空间的类型的 CodeTypeDeclaration 添加到 CodeNamespace 的 Types 集合 。

下列示例演示如何向名为 samples 的 CodeNamespace 添加名为 class1 的类 :

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

将类成员添加到类

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

为可执行文件定义一个代码入口点方法

若正在为可执行程序生成代码,则务必创建 CodeEntryPointMethod 来表示应开始程序执行的方法,以指示程序的入口点。

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

CodeEntryPointMethod^ start = gcnew CodeEntryPointMethod();
CodeMethodInvokeExpression^ cs1 = gcnew CodeMethodInvokeExpression(
    gcnew CodeTypeReferenceExpression("System.Console"),
    "WriteLine", gcnew 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);
Dim start As New CodeEntryPointMethod()
Dim cs1 As New CodeMethodInvokeExpression( _
    New CodeTypeReferenceExpression("System.Console"), _
    "WriteLine", new CodePrimitiveExpression("Hello World!"))
start.Statements.Add(cs1)

下列语句向 class1 的 Members 集合添加名为 Start 的入口点方法 :

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

现在,名为 compileUnitCodeCompileUnit 包含用于简单 Hello World 程序的 CodeDOM 图。 有关从 CodeDOM 图生成和编译代码的信息,请参阅从 CodeDOM 图生成源代码并编译程序

有关生成 CodeDOM 图的详细信息

CodeDOM 支持多种常见的代码元素,可用于支持公共语言运行时的编程语言。 CodeDOM 不是为了提供可表示所有可能的编程语言功能的元素。 可在 CodeSnippetExpressionCodeSnippetStatementCodeSnippetTypeMemberCodeSnippetCompileUnit 中封装无法通过 CodeDOM 元素轻易表示的代码。 但是,CodeDOM 无法自动将代码片段转换为其他语言。

有关各种 CodeDOM 类型的文档,请参阅 System.CodeDom 命名空间的参考文档。

有关用于查找表示特定代码元素类型的 CodeDOM 元素的快速图表,请参阅 CodeDOM 快速参考