在C#6中,您可以通過使用getter-only自動屬性來簡化實現屬性。例如,如果我實現抽象Stream
類:getter-only自動屬性和表達式主體屬性之間的區別是什麼?
public override bool CanRead { get; } = true;
但是我還可以用表達體寫,還新在C#6:
public override bool CanRead => true;
是什麼兩者之間的差,我應該什麼時候使用一個或另一個?
在C#6中,您可以通過使用getter-only自動屬性來簡化實現屬性。例如,如果我實現抽象Stream
類:getter-only自動屬性和表達式主體屬性之間的區別是什麼?
public override bool CanRead { get; } = true;
但是我還可以用表達體寫,還新在C#6:
public override bool CanRead => true;
是什麼兩者之間的差,我應該什麼時候使用一個或另一個?
它們是用於兩種不同事物的語法糖。前者初始化後臺字段,並在字段初始化期間將其設置爲賦值右側的表達式。後者創建了一個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」被印刷,因爲表達在對象的構造進行評價。
在你在我們的例子中描述的情況,我以前喜歡:
public override bool CanRead { get; } = true;
但是今天我通知這個實現事業爲後盾領域的內存分配。所以,這個實現:bool CanRead => true;
可以保存4個字節。
技術上在第一種情況下不是生成的後備字段也是'readonly'? – Kyle
後臺字段的分配就好像它是在字段初始化程序中分配的,而不是在構造函數的主體中分配的。如果基類調用虛構方法,您可以觀察到這種差異,該虛方法在構造函數體執行之前發生。這是一個微妙的差異,坦率地說:) –
@JonSkeet哦,你是對的,該領域是'initonly'。 – vcsjones