2010-06-19 50 views
1

我知道結構是值類型,但我不明白爲什麼這個工程:
編輯:我的意思是,爲什麼this.Size.Height不起作用呢?C#-2結構問題

struct A 
{ 
    int height; 

    public int Height 
    { 
     get 
     { 
      return height; 
     } 

     set 
     { 
      height = value; 
     } 
    } 
} 

//... class Main 
{ 
    A a = A(); 
    a.Height = 5; //works. Why? I thought it should say "cannot modify as it is not variable". I think the properties should return copy of this struct...? 
} 

第二個問題 - 我看過,我不需要用「新」與結構,但它不沒有它爲我工作。

+0

未來如果您有兩個問題,請考慮發佈*兩個*問題,而不是將它們組合成一個問題。這樣每個問題都有一組明確的答案。 – 2010-06-19 14:51:46

回答

1

「this.Size.Height = 5」不起作用,因爲當使用值類型作爲屬性的類型時,上面的代碼行實際上意味着「this.get_Size()。set_Height(5)」 ,並且get_Size()調用的結果是原始的副本,它是一個值類型。

因此,如果C#允許,將屬性值設置爲5會更改副本的值而不是原始屬性值,這非常不理想。

當然,這不適用於通過局部變量更改類的值類型屬性時,因此可以安全地支持此場景。

3

我認爲你是令人困惑的價值類型與不變性。我認爲this SO question會幫助你。

1

這是非常正常的。爲什麼你認爲它不能讓你爲高度設定價值? 屬性應該如何工作是非常正常的行爲。 關於調用new,是的,它對於值類型不是強制性的。對於值類型,它只是調用默認構造函數,它只是用默認值初始化字段。

0

屬性將返回其「get」方法返回的值。結構和類也是一樣的。如果你提供一個「set」方法,它將會執行任何「set」指示。 Height無法修改的唯一方法是使用私有「set」,或者根本不提供「set」。

6

讓我打破下來到幾個問題:

什麼是變量?

變量是包含值的存儲位置。

爲什麼值類型稱爲值類型?

值類型的變量的值是一個,通過複製。參考類型的變量的值是參考並且被參考複製。這就是爲什麼值類型稱爲值類型,而引用類型稱爲參考類型。

爲什麼a.Height = 10有效?

要更改存儲在引用類型變量中的值,必須先有一個變量。在這種情況下,你需要:你有變量「a」。編譯器將其編譯爲「將變量'a'的管理地址傳遞給Height參數10」。因此,Height屬性設置器知道如何找到存儲在'a'中的值的位置並對其進行變異。

爲什麼a.Size.Height = 10不起作用?

要更改存儲在引用類型變量中的值,必須先有一個變量。表達式「a.Size」不是一個變量;這是一個價值。 a.Size不會給你支持該屬性的變量 - 事實上,可能沒有。相反,它會給你財產的價值。值類型按值複製;這是該財產的價值的副本。這意味着編譯器有兩個選擇:它可以將值複製到臨時變量中,然後改變該變量,欺騙你認爲你已經改變了a.Size的後備存儲區。或者,它可能會給你一個錯誤,表明你在做一些愚蠢的事情。它做後者。

這難道不是令人困惑和煩惱嗎?

是的。故事的寓意是不要使可變值類型。只能使值不變值類型。從來沒有一個值類型的setter;只在構造函數中進行賦值。如果事物必須是可變的,則將其作爲參考類型。

我是否必須使用「new」來創建一個值類型的新實例?

號你也可以使用「默認」:

Foo f = default(Foo); 

如果foo是一個值類型,那麼這填補了存儲單元的內容f控制有其所有字段設置爲他們的富默認值。

或者,如果值類型是可變的,您可以簡單地設置所有字段的值。但是,如果您不使用構造函數或默認初始化程序,則必須設置它們全部爲的所有。您必須將其全部設置爲,包括專用字段

但是,如果一個結構體具有所有的公有字段並不違反最佳實踐指南的兩種方式?首先,因爲它具有公共領域,其次,因爲它是一個可變值類型?

是的。不要這樣做。