簡體   English   中英

Microsoft如何使所有.NET類隱式繼承自Object類? 我可以做同樣的事情嗎?

[英]How does Microsoft make all .NET classes implicitly inherit from the Object class? Can I do the same kind of thing?

我們創建的所有類都繼承自Object類,而無需顯式聲明該類的繼承。

  • Microsoft如何使所有.NET類隱式繼承自Object類?
  • 編譯器是否在幕后注入了這種繼承?
  • 我可以做同樣的事情:例如,讓我的所有類從類接口隱式繼承嗎?

我的問題可能含糊不清,所以我會澄清:

我不是要求繼承自Object以外的其他類,因為我知道禁止對類進行多重繼承。 我正在談論繼承,而不是通過類接口,我的問題是關於隱含地做的不是用我自己的另一個類替換一個對象,或者用Object和我自己的另一個類做多重繼承。 我希望所有類都繼承自Interface1OfMyOwn和Interface2OfMyOwn。

所有類都隱式擴展了Object因為C#標准指定了語言。

詢問他們如何實現這就像問他們如何實現void方法不返回數據的事實,或者他們如何實現類具有屬性的事實:它只是在編譯器的代碼中的某處(這里可能是C#編譯器或JIT編譯器)。 我們無法確切地知道,但是有理由說,只要編譯器沒有在類中檢測到顯式繼承,它就會改為System.Object ,就像那樣簡單。 因此,您必須接受Object只是編譯器的特殊類型

為什么你不能用自定義類做到這一點似乎顯而易見:它會使編譯器徹底混淆沒有顯式繼承的類是應該擴展Object還是自定義類。 如果它為沒有顯式繼承的每個類選擇后者,那么在大多數情況下會引入編譯錯誤,或者,如果你特別不走運,那么只會在運行時出現的令人驚訝的行為。 如果它選擇了前者而你必須明確選擇你的課程,那有什么意義呢?

(當然,如果你想隱式實現一個接口,也會發生這種情況:所有沒有真正實現該接口的類都會破壞並導致編譯錯誤。或者,如果你運氣不好,接口將匹配不相關的方法碰巧具有匹配簽名並導致您通過測試找到的奇怪行為的類。)

這在運行時內的非常低級別受支持,值類型的值可以嵌入存儲在垃圾收集堆中的對象中。 因此,在引用類型中轉換值類型並創建每個值類型從ValueType和Object繼承的錯覺。 哪些是參考類型。

該機制在.NET中調用裝箱 ,值類型值字面上被“裝箱”到一個對象中。 並且有一個拆箱轉換,從帶有盒裝值的對象返回到值類型的值。 C#編譯器將根據您的源代碼自動發出這些轉換。 有專門的操作碼是IL,C#編譯器從源代碼中發出的中間語言。 分別是Opcodes.Box和Opcodes.Unbox指令。 Opcodes.Constrained是一個可以優化轉換的指令。 抖動知道如何實現它們並生成非常有效的內聯機器代碼來進行這些轉換。

Boxing是System.Object的高度特定,它是類型層次結構中的基類,支持它的管道高度特定於值類型值。 它不是可擴展的機制,您不能添加自己的IL指令也不能擴展抖動,也不能為C#語言提供新的語法。 如果您需要類型具有公共基本接口或類,則必須在代碼中以這種方式聲明它們。 動態關鍵字可能對您有吸引力,但問題並不清楚。

我完全同意提供的兩個答案...只是想添加一個選項,你可以做什么來實現所需的結果,即“自動繼承自定義接口”:

您可以使用MSRoslyn項目對編譯過程進行非常深入的控制,但要注意Roslyn仍然沒有“生產就緒”。

您可以編寫一些代碼來影響編譯過程並分析甚至更改編譯器如何工作以實現您想要的。

值得關注的另一個選擇可能是AOP - 有一些.NET框架可以做出驚人的事情(例如見這里 )。

對於你想要的, object上的擴展方法將起作用。 您還可以使用泛型類型,它會立即丟失較少的類型信息。

static class GeneralMethods
{
    public static void Testing(this object This)
    {
        This.ToString().Dump("Testing");
    }

    public static void Test2<T>(this T This)
    {
        This.Dump("Test2");
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM