未來的C 之覆寫放寬

2021-09-17 03:53:27 字數 1859 閱讀 2977

能使用協變(covariant)返回型別,這是乙個在.net中常被請求到的特性。例如,可以使用「override widget clone()」覆寫「virtual object clone()」。從型別安全的角度看,這種做法完全可以接受,但是當前並不被c#所允許。

\\ 根據「對協變返回型別的建議」,該規則將被放寬,使得相比於基類中的方法,子類中的同一方法可以返回更具體的型別。除了上例中給出的clone方法之外,這種放寬對抽象工廠和其他框架**也會十分有用。

\\隱式投影(implicit shadowing)

\\

在c#中,一種可能的實現方法是發射(emit)兩個函式。還以clone方法為例,我們可以在中間語言(il)中看到如下的方法簽名(method signature):

\\

\override object clonable.clone()\public new widget clone()\
\\

按halofour的說法,這是可以工作的,原因在於:

\\

\

在通用語言執行庫(clr,common language runtime)規範中,看上去的確允許覆寫具有不同的名字,並可以具有不同的可見性(visibility)。

\\ \\

通過在il中顯式地使用「.override」語句,我能解決所有的過載決議(overload resolution)問題,並能使用具有不同可見性和名字的方法進行覆寫。

\

\\

該編譯器特性可與現有的clr版本無縫工作,並且舊版本的vb或c#將可以毫無問題地消費這樣的類。

\\ 但是這一做法也存在著一些限制。首先,從覆寫方法正常繼承而來的屬性是不能被拷貝到隱藏(new)方法中的。從技術上講,編譯器可以拷貝基類屬性到隱藏方法上。但是這種做法存在著問題,一旦新增隱藏屬性新增到基類方法,就將需要對子類進行重編譯。

\\ 其次,這也會導致在使用反射(reflection)時,難以看到隱藏方法與被覆寫的基類方法之間的關聯。

\\ 最後一點,這會對通過基類介面的呼叫方法產生效能上的影響。但是,該問題可以通過尾呼叫(tail call)及其他優化技術緩解。

\\屬性

\\ 在c#中,另一種可能的實現方法是使用新屬性。如果編譯器能識別該屬性,則會針對更具體的型別自動新增強制轉換(cast)。

\\ 該方法的乙個缺點在於,如果新屬性不能被語言所理解,就不能使用該方法。當然,新屬性也必須新增到基礎類庫(blc,base class library)中,這意味著它不會在所有的平台上立刻可用。

\\ 另乙個缺點是,它可能會在處理結構體時引入不必要的裝箱(boxing)操作。繼續以上面的clone方法為例,編譯器將必須裝箱乙個widgerstruct結構體,然後立刻將其強制轉換為乙個正常的widgetstruct結構體。

\\投影和覆寫的放寬

\\ 另一種替代做法是放寬對投影的限制規則。當前,乙個方法是不允許同時被投影和覆寫的。但是,考慮到clr是支援這種做法的,c#只是允許顯式地編寫如下**:

\\

\class widget : cloneable\\    public new widget clone()\    \}\
\\

根據隱式投影的建議,這將依賴編譯器去重新命名過載方法。

\\時間表

\\ 需要指出的是,大部分該特性相關的討論出現於2023年上半年,即兩年之前。但是該建議是在今年二月份才正式寫完,因此尚未採取任何行動,或者說尚未公開採取任何行動。

\\檢視英文原文:c# futures: relaxed overrides

覆寫Activity的finish 方法

mainactivity如下 package cn.testfinish import android.os.bundle import android.view.view import android.view.view.onclicklistener import android.widget....

多型的核心 方法覆寫

物件多型的核心是方法覆寫 1.向上轉型 引數統一化 把乙個子類的例項給了父類 父類 父類物件引用 子類例項 自動 person per new student 看等號的右邊 new的是哪個類,再呼叫的方法有沒有被new的類所覆寫 2.向下轉型 父類需要呼叫子類擴充的功能時 子類 子類物件引用 子類 ...

方法的覆寫和過載

在學習中 方法的覆寫和過載老是有人搞混 或者記不清他們之間的細節 方法的過載 概念 方法名稱相同,引數的個數或型別不同 不能有兩個名字相同,引數型別也相同卻返回值不同的方法 構造方法的過載 由於同乙個類中不可能有兩個屬性,名稱相同,型別不同所以構造方法的過載只能是引數的個數不同。方法覆寫 概念 子類...