[英]Is it possible to force an auto-property to use a readonly backing field?
我的項目包含大量具有屬性的類,其后備字段標記為只讀,因為它們僅在構造時設置。 作為一種風格問題,我喜歡使用自動屬性,因為它消除了大量的樣板代碼,並鼓勵使用屬性成員而不是支持字段。 但是,當使用自動屬性時,我失去了我的支持字段的“readonly-ness”。 我知道當字段以這種方式標記時,編譯器/運行時能夠利用一些性能增強,所以我希望能夠將我的auto-property標記為readonly,如下所示:
[ReadOnly]
public string LastName { get; }
而不是
private readonly string _LastName;
public string LastName
{
get
{
return _LastName;
}
}
有沒有一些機制可以做到這一點? 如果沒有,自定義支持字段的性能增益是否真的值得?
我認為,將該字段公開為公共是另一種選擇,以這種方式公開字段似乎是錯誤的。 即
public readonly string LastName;
我不敢,但你可以這樣做:
public string LastName { get; private set; }
不像readonly
那么好,但也不是太糟糕。
不,不幸的是沒有辦法做到這一點。 就個人而言,我認為C#中自動實現的屬性缺少兩件事 - 一個默認值(我認為將在VB10中)和只能在構造函數中設置的只讀屬性。 換句話說,我希望能夠做到:
public class Foo
{
public string Tag { get; internal set; } = "Default value";
// The "readonly" would imply "private" as it could only
// be set from a constructor in the same class
public int Value { get; readonly set; }
public Foo()
{
// Valid to set property here, but nowhere else
Value = 20;
}
}
正如Jared所提到的,這意味着將對屬性setter的編譯器調用更改為簡單的字段賦值,並確保它們僅在構造函數中發生。
這將使編寫不可變類型更簡單。 不幸的是,C#4的情況不會有所改善。我們希望我們能為C#5獲得類似的東西......
不,它不是,如果沒有重大調整,這個功能將毫無用處。
只能從構造函數中驗證readonly字段。 只能從生成的setter設置自動實現的屬性。 這些是不兼容的要求,將產生無法驗證的代碼。
是的,您可以使編譯器足夠智能以忽略setter並直接進入構造函數中的支持字段。 但在制定者本身仍然是無法核實的。 編譯器需要從生成的代碼中省略它,因為它將生成一個真正的只讀屬性。 這會產生另一個矛盾,因為您仍然需要對該屬性執行賦值語句。
Foo() {
SomeProperty = "somevalue";
}
在這種情況下,代碼看起來像是在屬性上調用setter。 但實際上沒有要調用的setter,因為它必須從最終代碼中省略。
編輯
這並不是說不能做到。 它可以但需要C#的一些工作。
特別是,他們必須提供一種方法來設置不具有設定器的屬性的支持字段。 有幾種方法可以做到這一點。
我不是說這些都是好的選擇,只是使這種類型的功能工作的可能性。
從C#6.0開始,答案是肯定的。 您的示例可以如下編寫,編譯器會自動生成屬性后面的只讀字段。 這稱為僅限getter的自動屬性。
public string LastName { get; }
來自https://msdn.microsoft.com/en-us/magazine/dn879355.aspx
結構和類聲明中都提供了僅限getter的自動屬性,但它們對結構特別重要,因為結構是不可變的最佳實踐指南。 而不是聲明一個只讀屬性並在C#6.0之前初始化它所需的六行左右,現在只需要單行聲明和構造函數中的賦值。 因此,不可變結構的聲明現在不僅是結構的正確編程模式,而且是更簡單的模式 - 從先前語法中非常理解的變化,其中編碼正確地需要更多努力。
我更喜歡真正的readonly
后備字段,因為這可以保證我在構建后不會更改后備字段。
不,不。 沒有辦法做到這一點,只讀備用字段沒有性能提升。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.