使用语义

语法树 表示源代码的词法和语法结构。 虽然仅此信息就足以描述源中的所有声明和逻辑,但它没有足够的信息来标识所引用的内容。 名称可能表示:

  • 一种类型
  • 字段
  • 一种方法
  • 局部变量

虽然每个标识符都是独一无二的,但确定标识符实际引用哪个标识符通常需要深入了解语言规则。

源代码中表示的程序元素,程序还可以引用以前编译的库(打包在程序集文件中)。 尽管没有源代码(因此没有语法节点或树)可用于程序集,但程序仍可以引用其中的元素。

对于这些任务,需要 语义模型

除了源代码的语法模型外,语义模型还封装了语言规则,使你能够轻松地将标识符与所引用的正确程序元素匹配。

汇编

编译是编译 C# 或 Visual Basic 程序所需的所有内容的表示形式,其中包括所有程序集引用、编译器选项和源文件。

由于所有这些信息都位于一个位置,因此可以更详细地描述源代码中包含的元素。 编译将每个声明的类型、成员或变量表示为符号。 编译包含多种方法,可帮助你查找和关联已在源代码中声明或从程序集导入为元数据的符号。

与语法树类似,编译是不可变的。 创建编译后,你或你可能与之共享的任何人都无法更改它。 然而,您可以从现有编译中创建新的编译,在此过程中指定更改。 例如,可以创建与现有编译相同的编译,只不过它可能包含其他源文件或程序集引用。

符号

符号表示由源代码声明或从程序集导入为元数据的不同元素。 每个命名空间、类型、方法、属性、字段、事件、参数或局部变量都由符号表示。

类型上的 Compilation 各种方法和属性可帮助你查找符号。 例如,可以通过声明类型的公用元数据名称查找符号。 您还可以将整个符号表作为一棵以全局命名空间为根的符号树来访问。

符号还包含编译器从源或元数据(如其他引用的符号)确定的其他信息。 每种类型的符号都由派生自 ISymbol的单独接口表示,每个符号都有自己的方法和属性,详细说明编译器收集的信息。 其中许多属性直接引用其他符号。 例如,该 IMethodSymbol.ReturnType 属性告知方法返回的实际类型符号。

符号在源代码和元数据之间呈现命名空间、类型和成员的常见表示形式。 例如,在源代码中声明的方法和从元数据导入的方法都由 IMethodSymbol 具有相同属性的方法表示。

符号在概念上与由 API 表示的 System.Reflection CLR 类型系统类似,但它们更丰富,因为它们的模型不仅仅是类型。 命名空间、局部变量和标签都是符号。 此外,符号是语言概念的表示形式,而不是 CLR 概念。 有很多重叠,但也有许多有意义的区别。 例如,C# 或 Visual Basic 中的迭代器方法是单个符号。 但是,当迭代器方法转换为 CLR 元数据时,它是一种类型和多个方法。

语义模型

语义模型表示单个源文件的所有语义信息。 可以使用它来发现以下内容:

  • 在源中特定位置处引用的符号。
  • 任何表达式的结果类型。
  • 所有诊断(错误和警告)。
  • 变量如何传入和流出源区域。
  • 更多推理问题的答案。