在C#中,循環引用是禁止的。編譯器會檢查循環引用,並且如果發 現了它,就會報告一個錯誤。然而,IL並不檢查循環引用,因為Microsoft不希望所有的程序員都使用純 的IL。
因此,類aa繼承自類bb,類bb繼承自類cc,最後類cc又繼承自類aa。這就形成了一個循環 引用。在運行時拋出的異常不會給出循環引用的任何跡象。從而,如果我在這裡沒有為你揭示這個秘密, 那麼這個異常就可能讓你感到困惑。我並不打算顯擺對理解IL有多深這樣的事實,但是偶爾給出一些提示 信息是無妨的。
a.cs
internal class zzz
{
public static void Main()
{
}
}
a.il
.assembly mukhi {}
.class private auto ansi zzz extends [mscorlib]System.Object
{
.method public hidebysig static void vijay() il managed
{
.entrypoint
ret
}
}
訪問修飾符,如關鍵字internal,只是C#詞法的一部分,而與IL沒有任何關系。關鍵字internal表示這個 特定的類只能在它所在的文件中被訪問到。
因此,通過掌握IL,我們能夠區分.Net核心和C#領域 存在的特性之間的不同。
a.il
.assembly mukhi {}
.class private auto ansi zzz extends [mscorlib]System.Object
{
.method public hidebysig static void vijay() il managed
{
.entrypoint
ret
}
}
.class public auto ansi yyy extends xxx
{
}
.class private auto ansi xxx extends [mscorlib] System.Object
{
}
在C#中,有一條規則:基類的可訪問性要大於派生類。這 條規則在IL中不適用。從而,即使基類xxx是私有的而派生類yyy是公共的,也不會在IL中生成任何錯誤。
a.il
.assembly mukhi {}
.class private auto ansi zzz extends [mscorlib]System.Object
{
.method public hidebysig static void vijay() il managed
{
.entrypoint
ret
}
}