2017-09-05 48 views
151

我有時會在getter的屬性中看到縮寫。例如。這兩種類型:不同的getter樣式之間的C#差異

public int Number { get; } = 0 

public int Number => 0; 

有人可以告訴我,如果這兩者之間有任何區別。他們如何表現?他們都是隻讀嗎?

回答

262

是的,它們都是隻讀的,但是有區別。在第一個中,有一個支持字段在構造函數執行之前被初始化爲0。您只能在構造函數中更改值,就像常規只讀字段一樣。 getter本身只是返回字段的值。

在第二個中,getter只是每次返回0,沒有涉及到字段。

所以要避免使用任何自動實現的屬性或表達健全成員所有,我們有:

第一版

private readonly int _number = 0; 
public int Number { get { return _number; } } 

第二個版本

public int Number { get { return 0; } } 

一更清晰的差異示例可能會看起來像這樣:

public DateTime CreationTime { get; } = DateTime.UtcNow; 
public DateTime CurrentTime => DateTime.UtcNow; 

如果創建一個對象,它的CreationTime屬性將始終產生相同的結果 - 因爲它存儲在只讀領域,對施工對象初始化。但是,每次訪問CurrentTime屬性時,都會導致對DateTime.UtcNow進行評估,因此您將得到可能不同的結果。

+22

請注意,第二個版本並不總是返回相同的值。一個很好的例子是如果你返回'random.NextInt()'。第一個版本將評估一次,並始終具有相同的價值。第二個將每次返回一個新值。 – Hosch250

20

這些是C#6語言功能。

第一示例

public int Number { get; } = 0 

第一個例子是一個getter-only auto property。只有getter的auto屬性的後臺字段被隱式聲明爲只讀。

第二示例

public int Number => 0; 

而第二個例子是expression bodies on property-like function members。請注意,沒有任何get關鍵字:它通過使用表達式主體語法來暗示。

兩者都是隻讀的。

+4

...但正如Jon Skeet解釋的那樣,您可以更改第一個返回的值。 –

+1

@MartinBonner ...但只在構造函數中。 –

+4

或一如既往地通過反思(小挑逗) –

246

一個區別是0被評估時:在創建對象或使用屬性時。

你可以看到這個更好的DateTime屬性:

class SomeTestClass 
{ 
    public DateTime Start { get; } = DateTime.Now; 

    public DateTime Now => DateTime.Now; 
} 

Start財產不斷返回相同的時間(創建實例時),而Now變化,以反映當前時間。

說明

第一個版本(「開始」)提供,其可以甚至由構造被覆蓋的初始值。所以這隻被評估一次。
第二個版本(「現在」)提供了將成爲該屬性的「getter」的表達式。所以每次讀取屬性時都會對其進行評估。甚至沒有構造函數可以覆蓋的支持字段。

+24

這是我認爲的最重要的區別。 – Matthew

+13

接受的答案最準確地定義了示例代碼中的差異,但這解釋了兩個結構中更有用的差異。 –

+2

哇,你比起着名的Jon Skeet本人得到了更多的選票。 –