2015-10-07 40 views
0

讓我們來看下面的代碼。爲什麼c#中的unboxed結構體右值

struct SPoint 
{ 
    public int x; 
    public int y; 

    public SPoint(int x, int y) 
    { 
     this.x = x; 
     this.y = y; 
    } 
} 

class Test 
{ 

    public static void Main() 
    { 
     SPoint s = new SPoint(3, 4); 
     object o = s; 
     ((SPoint) o).x = 5; 
    } 
} 

爲什麼不是最後的賦值可能?這種行爲的原因是什麼?

+1

邊注:您的結構是可變的。檢查出http://stackoverflow.com/questions/441309/why-are-mutable-structs-vil –

回答

1

由於sstruct(又名:一value type),(SPoint)o是數據的副本:

從C#語言規範(§1.3, 「類型和變量」):

將值類型的值轉換爲類型對象時,將分配一個對象實例(也稱爲「框」)來保存該值,並將該值複製到該框中。相反,當對象引用強制轉換爲值類型時,會檢查被引用對象是否爲正確值類型的框,如果檢查成功,則將框中的值複製出來。

語言保護您更改數據克隆的價值型沒有把它在一個可變的第一,因爲你可能會想,而你是,你是改變原來s.x值改變它的臨時(不可變)克隆,不像不安全的語言,如可能允許這種分配的C++/CLI。

如果你願意,你可以明確地創建一個新的變量,並做你的操作在裏面:

SPoint cloneOfS = ((SPoint)o); 
cloneOfS.x = 5; 
1

參見MSDN

取消裝箱轉換的結果是一個臨時變量。編譯器會阻止你修改這些變量,因爲當臨時變量消失時,任何修改都會消失。要解決此問題,請聲明一個新的值類型變量來存儲中間表達式,並將拆箱轉換的結果分配給該變量。