接下來的一系列程序與預處理指令有關,這與C#編譯器是不同的 。只有預處理指令能夠理解它們。
在上面的.cs程序中,#define指令創建了一個名為 "vijay"的詞。編譯器知道#if語句是TRUE,因此,它會忽略#else語句。從而,所生成的IL文 件只包括具有參數'1'的WriteLine函數,而不是具有參數'2'的那個。
這就涉及 到了編譯期間的知識。大量不會使用到的代碼,會在被轉換為IL之前,被預處理直接除去。
a.cs
#define vijay
#undef vijay
#undef vijay
class zzz
{
public static void Main()
{
#if vijay
System.Console.WriteLine("1");
#endif
}
}
a.il
.assembly mukhi {}
.class private auto ansi zzz extends [mscorlib]System.Object
{
.method public hidebysig static void vijay() il managed
{
.entrypoint
ret
}
}
我們可以使用很多#undef語句,只要我們喜歡。編譯器知道'vijay'這個詞被事 先定義了,之後,它會忽略#if語句中的代碼。
在從IL到C#的再次轉換中,原始的預處理指令是無 法被恢復的。
a.cs
#warning We have a code red
class zzz
{
public static void Main()
{
}
}
C#中的預處理指令#warning,用於為運行編譯器的程序員顯示警告。
預處理指令 #line和#error並不會生成任何可執行的輸出。它們只是用來提供信息。
繼承
a.cs
class zzz
{
public static void Main()
{
xxx a = new xxx();
a.abc();
}
}
class yyy
{
public void abc()
{
System.Console.WriteLine("yyy abc");
}
}
class xxx : yyy
{
}
a.il
.assembly mukhi {}
.class private auto ansi zzz extends [mscorlib]System.Object
{
.method public hidebysig static void vijay() il managed
{
.entrypoint
.locals (class xxx V_0)
newobj instance void xxx::.ctor()
stloc.0
ldloc.0
call instance void yyy::abc()
ret
}
}
.class private auto ansi yyy extends [mscorlib]System.Object
{
.method public hidebysig instance void abc() il managed
{
ldstr "yyy abc"
call void [mscorlib]System.Console::WriteLine(class System.String)
ret
}
}
.class private auto ansi xxx extends yyy
{
}
Output
yyy abc