共用方式為


中繼資料的執行階段使用

若要更了解中繼資料和它在 Common Language Runtime 中的角色,建構簡單程式並說明中繼資料如何影響它的執行階段存留期,可能很有幫助。 下列程式碼範例展示稱為 MyApp 的類別內的兩個方法。 Main 方法為程式進入點,而 Add 方法只是傳回兩個整數引數的總和。

Public Class MyApp
   Public Shared Sub Main()
      Dim ValueOne As Integer = 10
      Dim ValueTwo As Integer = 20
      Console.WriteLine("The Value is: {0}", Add(ValueOne, ValueTwo))
   End Sub
   
   Public Shared Function Add(One As Integer, Two As Integer) As Integer
      Return (One + Two)
   End Function
End Class
using System;  
public class MyApp
{
   public static int Main()
   {
      int ValueOne = 10;
      int ValueTwo = 20;         
      Console.WriteLine("The Value is: {0}", Add(ValueOne, ValueTwo));
      return 0;
   }
   public static int Add(int One, int Two)
   {
      return (One + Two);
   }
}

當執行程式碼時,Runtime 將模組載入記憶體,並查閱中繼資料以取得這個類別。 一旦載入後,Runtime 會對該方法的 Microsoft Intermediate Language (MSIL) 資料流做一個廣泛的分析,以將它轉換為快速的原生機器指令。 Runtime 使用 Just-in-Time (JIT) 編譯器,按所需一次一個的方法轉換 MSIL 指令至原生機器碼 (Machine Code)。

下列範例展示從前面程式碼的 Main 函式產生的部分 MSIL。 您可以使用 MSIL 反組譯工具 (Ildasm.exe) 來檢視任何 .NET Framework 應用程式中的 MSIL 和中繼資料。

      .entrypoint
      .maxstack  3
      .locals ([0] int32 ValueOne,
               [1] int32 ValueTwo,
               [2] int32 V_2,
               [3] int32 V_3)
      IL_0000:  ldc.i4.s   10
      IL_0002:  stloc.0
      IL_0003:  ldc.i4.s   20
      IL_0005:  stloc.1
      IL_0006:  ldstr      "The Value is: {0}"
      IL_000b:  ldloc.0
      IL_000c:  ldloc.1
      IL_000d:  call int32 ConsoleApplication.MyApp::Add(int32,int32) /* 06000003 */

JIT 編譯器會讀取整個方法的 MSIL、全面分析它,並產生那個方法的有效率的原生指令。 在 IL_000d 上會遇到 Add 方法的中繼資料語彙基元 (/* 06000003 */),而執行階段即利用語彙基元查閱 MethodDef 表格的第三列。

下表顯示 MethodDef 表格中,由描述 Add 方法的中繼資料語彙基元所參考的部分。 雖然尚有其他中繼資料表存在於這個組件中並擁有其唯一值,但只有這個表格在討論之列。

表格列

相關的虛擬位址 (RVA)

ImplFlags

旗標

名稱

(指向字串堆積)

簽章 (指向 BLOB 堆積)

1

0x00002050

IL

Managed

Public

ReuseSlot

SpecialName

RTSpecialName

.ctor

.ctor (建構函式)

 

2

0x00002058

IL

Managed

Public

Static

ReuseSlot

Main

String

3

0x0000208c

IL

Managed

Public

Static

ReuseSlot

Add

int, int, int

表格的每一欄包含您程式碼的重要資訊。 RVA 欄允許執行階段計算定義這個方法的 MSIL 的起始記憶體位址。 ImplFlagsFlags 欄包含描述方法的位元遮罩 (例如,方法是否為 Public 或 Private)。 Name 欄對字串堆積中的方法名稱進行索引。 Signature 欄對 BLOB 堆積中方法簽章 (Signature) 的定義進行索引。

Runtime 計算第三列中 RVA 欄的所需位移 (Offset) 位址,並傳回這個位址到 JIT 編譯器,並接著進入新位址。 JIT 編譯器在新位址繼續處理 MSIL 直到遭遇另一個中繼資料語彙基元,並重複這過程。

藉著使用中繼資料,Runtime 擁有對載入您程式碼所需全部資訊的存取權,並處理它成為原生機器指令。 以這個方式,中繼資料允許自我描述檔案和連同一般型別系統的跨語言繼承。

請參閱

概念

中繼資料和自我描述元件

Managed 執行程序