2012-11-01 24 views
24

我不明白。該As操作:結構上的as運算符?

The as operator is used to perform certain types of conversions between compatible reference or nullable types.

那麼,爲什麼下面的工作?

struct Baby : ILive 
{ 
    public int Foo { get; set; } 

    public int Ggg() 
    { 
     return Foo; 
    } 
} 

interface ILive 
{ 
    int Ggg(); 
} 

void Main() 
{ 
    ILive i = new Baby(){Foo = 1} as ILive; // ?????? 
    Console.Write(i.Ggg());     // Output: 1 
} 
  • Baby是一個結構,創建它會把價值stack。這裏有沒有參考。

  • 這裏肯定沒有可以爲空的類型。

任何解釋爲什麼我錯了?

+0

順便說一句,像Baby這樣的可變對象會造成一個糟糕的結構。一門課將是一個更明顯的選擇。 –

+0

@MarcGravell當然。但這個問題是爲了更好地瞭解邊緣情景。 :-) –

回答

34

將其作爲接口投入將在託管堆上創建一個盒裝副本,並返回對盒裝副本的引用。該框實現了界面。

+0

不接口的事實不會繼承System.object,有什麼關係嗎? –

+4

@RoyiNamir毫無疑問。接口總是引用類型,泛型只有一點例外,它們可以是*約束*類型(引用類型和值類型之間的中間值) –

9

它的工作原理是因爲右側是一個界面。條件是右側可以接受null作爲值,即它是一個引用類型或可爲空的值類型。接口是一個引用類型。在這種情況下,代碼將打包結構,然後將裝箱的對象轉換爲接口。

+0

任何具有接口的靜態類型的東西都是引用。如果你將一個值類型轉換爲一個接口,它將被裝箱(給你一個參考)。所以在這種情況下,有理由稱它們爲引用類型。 – CodesInChaos

+0

像往常一樣,「任何」都有一個* partial *異常:當通過一些'T'上的通用約束來描述時,一個接口。雖然「約束」部分只適用於當變量爲「T」時 - * *而不是*當它是接口本身。 –

0

您只需使用參考類型ILive進行投票,因此不會拋出錯誤。但是,如果您嘗試使用該評論代碼,則會出現錯誤。

Baby b = new Baby(); 
object o = b; 
//Baby bb = o as Baby ; 

這是因爲您試圖使用as轉換爲值類型,並且不能爲空。