2012-07-05 49 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

它是因为静态构造函数只能与其他静态成员一起使用,而非静态构造函数需要实例化该对象。所以,如果你实例化类,但类有一个静态构造函数,构造函数将永远不会被调用。

相关问题