2012-07-05 53 views
3

有這樣的代碼:爲什麼我可以更改一個私有靜態只讀字段,但不是公共的?

public static readonly bool MaximumRecipientsReached; 
    private static readonly IList<EmailAddress> Contacts; 

    static AdditionalRecipient() 
    { 
     Contacts = AnotherClass.Contacts; //works 
    } 

    public AdditionalRecipient() 
    { 
     MaximumRecipientsReached = true; //works not 
    } 

我爲什麼可以改變一個私人靜態只讀字段,但不公開招標?

PS:當然我正在使用屬性。

+0

你得到的錯誤信息是什麼? – Servy 2012-07-05 13:48:47

回答

11

在第一個示例中,您將在靜態構造函數中對其進行更改,如果您在其他任何靜態方法/屬性中對其進行了更改,則會出現編譯器錯誤。

在第二個示例中,您試圖在非靜態構造函數中更改static readonly成員,這是不允許的。

您只能在static構造函數中更改static readonly成員。這樣想,static構造函數會運行一次,然後爲每個實例調用實例構造函數。如果每個實例都可以更改它,該屬性將不是readonly

你可以,當然,在構造改變非staticreadonly實例成員:

public static readonly bool MaximumRecipientsReached = false; 
public readonly bool MyInstanceReadonly = false; 

static AdditionalRecipient() 
{ 
    // static readonly can only be altered in static constructor 
    MaximumRecipientsReached = true; 
} 

public AdditionalRecipient() 
{ 
    // instance readonly can be altered in instance constructor 
    MyInstanceReadonly = true; 
} 

而且,我對你們的困惑「PS:當然我使用的屬性」。屬性不能被聲明爲readonly,如果你想要這些是屬性並且是readonly -ish,那麼你需要使它們成爲private set - 除非你使用的是後臺字段。我提出的主要原因是因爲使用具有私有集合的屬性將允許您執行代碼嘗試執行的操作,因爲類本身可以在任何方法或構造函數中更改屬性(靜態或實例),但代碼課外不能。

// public getters, private setters... 
public static bool MaximumRecipientsReached { get; private set; } 
public static IList<EmailAddress> Contacts { get; private set; } 
+0

感謝您的好評! – cfischer 2012-07-05 13:55:35

+0

@ChristianFischer:隨時,這就是我們在這裏;-) – 2012-07-05 13:57:50

2

它與公共與私有無關,而是靜態與非靜態構造函數無關。

如果您嘗試設置在非靜態構造函數靜態只讀項目(如在第二種情況下),編譯器會抱怨:

靜態只讀域不能被分配到(除靜態 構造函數或變量初始值)

這是因爲靜態成員的類型,其可以是任何常規構造甚至調用之前的第一接入初始化。靜態只讀成員可以從實例構造函數中修改是沒有意義的,因此編譯器會防止它。

只需將相關成員設置爲非靜態或將初始化放入靜態構造函數即可。

1

MaximumRecipientsReached是隻讀靜態的,您試圖從非靜態構造函數中進行設置。你只能在靜態構造函數中設置它。

0

它是因爲靜態構造函數只能與其他靜態成員一起使用,而非靜態構造函數需要實例化該對象。所以,如果你實例化類,但類有一個靜態構造函數,構造函數將永遠不會被調用。

相關問題