簡體   English   中英

編譯時和運行時強制轉換C#

[英]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.

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