中繼資料語彙基元

中繼資料是指有關抽象的宣告資訊,包括執行階段類型 (類別、值類型和介面)、全域函式和全域變數。 中繼資料儲存在資料表中 — 每個抽象類別各一個資料表,而每個抽象宣告各一列資料表。 語彙基元 (類型 mdToken 的物件) 可用來尋找包含抽象中繼資料的記錄。 中繼資料引擎會使用語彙基元,在給定的中繼資料範圍內,編製索引為特定的中繼資料表。

中繼資料語彙基元結構

中繼資料語彙基元為 4 位元組值。 最大顯著性位元組 (MSB) 會指定語彙基元類型,因此可識別抽象及其相關聯的中繼資料表。 例如,MSB 中的值 1 表示該語彙基元為代表類型參考的 mdTypeRef 語彙基元,且其中繼資料儲存在 TypeRef 中繼資料表中;MSB 中的值 4 對應於 mdFieldDef 語彙基元。 CorTokenType 列舉可用來指定語彙基元類型。

下面的三個位元組 (也就是記錄識別項 (RID)) 包含語彙基元 MSB 所參考之中繼資料表中的資料列索引。 例如,值為 0x02000007 的中繼資料語彙基元會參考目前範圍內 TypeDef 資訊表中的第 7 列。 同樣地,語彙基元 0x0400001A 會參考目前範圍內 FieldDef 資訊表中的第 26 (十進位) 列。 中繼資料表的第零列絕不會包含資料,所以 RID 為零的中繼資料語彙基元亦稱為「nil 語彙基元」(nil token)。 中繼資料 API 會定義這類 nil 語彙基元的主機,每個語彙基元類型各一個主機,例如 mdTypeRefNil,且值為 0x01000000。

注意事項注意事項

之前的 RID 解釋是概念性的,實際上,中繼資料的實體配置複雜多了,此外,字串語彙基元 (mdString) 有點不同 — 下面的 3 個位元組不是記錄識別項,而是代表在中繼資料字串集區中,與字串開始位置的偏差。

使用中繼資料語彙基元

中繼資料 API 中的每個 DefineXXX 方法會傳回一個語彙基元,可將該語彙基元傳遞至 GetXXX 方法,以取得其相關聯的屬性。

中繼資料語彙基元會定義在範圍內。 例如,值為 N 的中繼資料語彙基元可完整識別 (在給定範圍內) 含有類型定義詳細資料的記錄。 不過,在不同的範圍內,具有相同值 N 的中繼資料語彙基元可能會指定完全不同的記錄。

中繼資料語彙基元不是不可變中繼資料物件識別項。 當兩個範圍合併時,來自匯入範圍的語彙基元會重新對應至發出範圍內的語彙基元中。 儲存中繼資料範圍後,各種格式最佳化都會導致語彙基元對應。

語彙基元類型

下表列出中繼資料語彙基元類型、每個語彙基元類型所代表的抽象,以及含有抽象中繼資料之中繼資料表的名稱。 所有語彙基元類型都是 mdToken 的變化,這是基本語彙基元類型。 mdToken 定義在 CorHdr.h 標頭檔中,如下所示:

typedef ULONG32 mdToken;

語彙基元類型

中繼資料表

抽象

mdModule

Module

模組:編譯單位、可執行檔或某些其他開發單位、部署單位或執行時期單位。 您可以 (但非必要) 在整個模組上宣告屬性,包括名稱、GUID、自訂屬性等等。

mdModuleRef

ModuleRef

模組參考:對模組的編譯時期參考,這會記錄類型和成員匯入的來源。

mdTypeDef

Typedef

類型宣告:執行階段參考類型 (類別或介面) 或值類型的宣告。

mdTypeRef

TypeRef

類型參考:對執行階段參考類型或值類型的參考。 就某種意義來說,模組中的類型參考集合是編譯時期匯入相依性的集合。

mdMethodDef

MethodDef

方法定義:將方法定義為類別或介面的成員,或定義為全域模組層級方法。

mdParamDef

ParamDef

參數宣告:定義用來儲存參數其他中繼資料的選用性資料結構。 不需要針對方法中的每個參數發出資料結構。 不過,當有需要為參數留存的其他中繼資料時 (例如封送處理或類型對應資訊),可以建立選用性的參數資料結構。

mdFieldDef

FieldDef

欄位宣告:宣告變數為類別或介面的資料成員,或是宣告全域模組層級變數。

mdProperty

屬性

屬性宣告:宣告屬性為類別或介面的成員。

mdEvent

事件

事件宣告:宣告具名事件為類別或介面的成員。

mdMemberRef

MemberRef

成員參考:參考方法或欄位。 針對目前模組中任何實作所進行的每個方法引動過程或欄位存取,都會在中繼資料中產生成員參考,而且語彙基元會存留在 Microsoft 中繼語言 (MSIL) 資料流中。 沒有針對屬性或事件參考的執行階段支援。

mdIfaceImpl

IfaceImpl

介面實作:特定類別的特定介面實作。 此中繼資料抽象可讓您儲存非專屬於類別也非專屬於介面的交集資訊。

mdMethodImpl

MethodImpl

方法實作:針對使用介面繼承來繼承的方法,進行特定類別的實作。 此中繼資料抽象可讓專屬於實作而非合約的資訊留存。 實作類別無法修改方法宣告資訊。

mdCustomAttribute

CustomAttribute

自訂屬性:可以用 mdToken 來參考之任何中繼資料物件的相關任意資料結構。 (除外條件是,自訂屬性本身不能有自訂屬性。)

mdPermission

權限

權限集合:與 mdTypeDefmdMethodDefmdAssembly 相關聯的宣告式安全性權限集合。 如需詳細資訊,請參閱加入宣告式安全性支援

mdTypeSpec

TypeSpec

類型建構函式:此方法會針對類型 (例如 Boxed 實值類型) 來取得語彙基元,此語彙基元可用來做為採用類型之任何 MSIL 指令的輸入。

mdSignature

簽章

獨立式簽章:可攜式執行檔 (PE) 中的區域變數簽章,或是傳遞至 MSIL 指令的方法簽章。

mdString

String

使用者字串:傳遞至 MSIL 指令的字串。

注意事項注意事項

上述清單沒有包含您可能會預期的兩個不同語彙基元類型,一個適用於欄位參考,另一個適用於方法參考。欄位和方法參考共用相同的資訊表,並可使用語彙基元類型 mdMemberRef 來加以參考。

擴充性與抽象

執行階段中繼資料可擴充,這在下列情節中相當重要:

  • 為了表示 Common Language Specification (CLS) 所定義的條件約束或較高層級抽象。 CLS 是一種慣例規格,語言和工具同意以統一方式支援此規格,以促進語言整合。 CLS 可能會限制部分一般類型系統模型,而且 CLS 可能會引進在一般類型系統上層的較高層級抽象。 中繼資料必須能夠擷取工具所使用的這些開發時間抽象類型,即使執行階段未明確辨識或支援抽象也一樣。

  • 為了表示不屬於一般類型系統,而且不是 CLS 抽象的語言特定抽象。 這可以讓 Visual C 之類的語言不需要不同的標頭檔或 IDL 檔,即可使用已編譯模組所匯出的類型、方法和資料成員。

  • 為了將語言特定多載中使用的成員中簽章類型和類型修飾詞編碼。

中繼資料擴充性有下列形式:

  • 每個中繼資料物件都可以支援自訂屬性,而且中繼資料 API 提供了宣告、列舉和擷取自訂屬性的方式。 自訂屬性可以藉由依類型參考 (mdTypeDefmdTypeRef) 來識別。 自訂屬性的結構會自我描述、使用類型上宣告的資料成員,而且值編碼可以用任何工具來瀏覽,包括執行階段反映服務。

  • 除了擴充一般類型系統,還可以發出自訂修飾詞至成員簽章中。 執行階段將會遵照這些修飾詞來進行方法多載和隱藏,以及進行繫結,但不會強制使用任何語言特定語意。

請參閱

其他資源

中繼資料概觀