2015-01-12 66 views
45

在C#6中,您可以通過使用getter-only自動屬性來簡化實現屬性。例如,如果我實現抽象Stream類:getter-only自動屬性和表達式主體屬性之間的區別是什麼?

public override bool CanRead { get; } = true; 

但是我還可以用表達體寫,還新在C#6:

public override bool CanRead => true; 

是什麼兩者之間的差,我應該什麼時候使用一個或另一個?

回答

51

它們是用於兩種不同事物的語法糖。前者初始化後臺字段,並在字段初始化期間將其設置爲賦值右側的表達式。後者創建了一個get,它完全符合表達式中的內容。

public override bool CanRead { get; } = true; 

相當於

private readonly bool __backingFieldCanRead = true; 

public override bool CanRead 
{ 
    get 
    { 
     return __backingFieldCanRead; 
    } 
} 

public override bool CanRead => true; 

相當於

public override bool CanRead 
{ 
    get 
    { 
     return true; 
    } 
} 

他們的行爲不同。第一種情況是在創建對象並初始化字段時設置屬性的值,另一種情況是每次調用屬性的getter時評估表達式。在布爾的簡單情況下,行爲是相同的。但是如果表達引起副作用,情況就不同了。考慮這個例子:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var fooBar1 = new FooBar(); 
     Console.WriteLine(fooBar1.Baz); 
     Console.WriteLine(fooBar1.Baz); 
     var fooBar2 = new FooBar(); 
     Console.WriteLine(fooBar2.Baz); 
     Console.WriteLine(fooBar2.Baz); 
    } 
} 

public class FooBar 
{ 
    private static int counter; 
    public int Baz => counter++; 
} 

這裏打印「0,1,2,3」。每次調用屬性的getter時,靜態counter字段都會增加。然而,利用一個屬性初始化:

public int Baz { get; } = counter++; 

然後「0,0,1,1」被印刷,因爲表達在對象的構造進行評價。

+1

技術上在第一種情況下不是生成的後備字段也是'readonly'? – Kyle

+5

後臺字段的分配就好像它是在字段初始化程序中分配的,而不是在構造函數的主體中分配的。如果基類調用虛構方法,您可以觀察到這種差異,該虛方法在構造函數體執行之前發生。這是一個微妙的差異,坦率地說:) –

+1

@JonSkeet哦,你是對的,該領域是'initonly'。 – vcsjones

0

在你在我們的例子中描述的情況,我以前喜歡:

public override bool CanRead { get; } = true; 

但是今天我通知這個實現事業爲後盾領域的內存分配。所以,這個實現:bool CanRead => true;可以保存4個字節。

相關問題