[英]Compile-time and runtime casting c#
我想知道為什么在編譯時檢查C#中的某些強制類型轉換,而在其他情況下將責任轉交給CLR。 像上面一樣,兩者都是錯誤的,但是以不同的方式處理。
class Base { }
class Derived : Base { }
class Other { }
static void Main(string[] args)
{
Derived d = (Derived)new Base(); //Runtime InvalidCastException
Derived d = (Derived)new Other(); //Compile-time Cannot convert type...
}
在閱讀“ C#深入”時,我發現了有關該主題的信息,指導者說:
“如果編譯器發現該強制轉換實際上是不可能的,它將觸發編譯錯誤-如果理論上允許但實際上在執行時不正確,則CLR將引發異常。”
“理論上”是指通過繼承層次結構(對象之間的另一種親緣關系?)相連還是編譯器的內部事務?
編譯器僅考慮靜態類型。 運行時檢查動態(運行時)類型。 查看您的示例:
Other x = new Other();
Derived d = (Derived)x;
x
的靜態類型為Other
。 這與“ Derived
無關,因此強制轉換在編譯時失敗。
Base x = new Base();
Derived d = (Derived)x;
x
的靜態類型現在為Base
。 Base
類型的東西可能具有動態類型Derived
,所以這是一個垂頭喪氣的事情。 通常,編譯器無法從x
的靜態類型中得知運行時類型是否是Base
的其他子類的Base
Derived
。 因此,是否允許強制轉換的決定留給運行時。
如果您的變量是Base
類型,則理論上可以由Derived
構造函數構造,因此實際上是Derived
類型的變量。 在編譯時,編譯器不會試圖弄清楚在每種特定情況下是否都可能進行這種下調(將Base
類型的變量表示為Derived
類型的實體),這使編譯器不會費心。
您的示例很簡單-您創建一個新類並立即進行投射。 但是,如果您從其他地方獲得Base
,例如某個方法調用,該怎么辦? 編譯器無法“猜測”您的方法將返回什么,因此拋出錯誤不會拋出錯誤。
當您轉換Other
,編譯器會發現Other
實際上沒有Derived
並會引發異常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.