Question

having code like this:

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

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

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

Why can I change a private static readonly field but not a public one?

PS: of course I am using properties.

Was it helpful?

Solution

In your first example, you are changing it in the static constructor, which is allowed, if you changed it in any other static method/property, it would be a compiler error.

In your second example, you are attempting to change a static readonly member in a non-static constructor, which isn't allowed.

You can only change static readonly members in the static constructor. Think of it this way, the static constructor runs once, and after that for each instance the instance constructor is invoked. The property wouldn't be very readonly if every instance could change it.

You can, of course, change non-static readonly instance members in the constructor:

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;  
}

Also, I'm confused by your "PS: of course I am using properties". Properties cannot be declared readonly, if you wanted these to be properties and to be readonly-ish, you'd need to make them private set - unless of course you are using a backing field. The main reason I bring this up is because using a property with a private set would allow you to do what your code is trying to do, as the class itself can change the property (static or instance) in any method or constructor, but code outside of the class can not.

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

OTHER TIPS

It has nothing to do with public vs. private, but instead static vs. non-static constructors.

If you try to set a static readonly item in a non-static constructor (as in your second case), the compiler complains:

A static readonly field cannot be assigned to (except in a static constructor or a variable initializer)

This is because static members are initialized on first access of the type, which could be before any regular constructors are even called. It makes no sense to have static readonly members modifiable from instance constructors, hence the compiler guards against it.

Simply either make the relevant member non-static or put the initialization into the static constructor.

MaximumRecipientsReached is readonly static and you are trying to set it from a non static constructor. You can only set it inside your static constructor.

Its because static constructors can be used only with other static members and the non-static ones need the object to be instantiated. So if you instantiate the class but the class has a static constructor the constructor will never get called.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top