使用 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 对象图,该对象图塑造要编译的源代码的模型。 A 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命名空间的导入添加到Imports命名CodeNamespacesamples集合中:

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

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

以下语句将 samplesCodeNamespace 添加到 NamespacesCodeCompileUnit 的集合属性。

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添加到CodeNamespaceTypes集合中。

以下示例演示如何向名为samplesCodeNamespace中添加一个类class1

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

将类成员添加到类

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

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

若正在为可执行程序生成代码,则务必创建 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)

以下语句将命名 Start 的入口点方法添加至 class1Members 集合中:

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

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

有关生成 CodeDOM 图的详细信息

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

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

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