为什么我可以更改私有静态只读字段而不是公共字段?

时间:2012-07-05 13:41:07

标签: c# constructor readonly static-constructor

有这样的代码:

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

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

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

为什么我可以更改私有静态只读字段而不是公共字段?

PS:当然我正在使用属性。

4 个答案:

答案 0 :(得分:11)

在第一个示例中,您将在静态构造函数中更改它,这是允许的,如果您在任何其他静态方法/属性中更改它,那将是编译器错误。

在第二个示例中,您试图在非静态构造函数中更改static readonly成员,这是不允许的。

您只能更改static readonly构造函数中的static个成员。可以这样想,static构造函数运行一次,然后为每个实例调用实例构造函数。如果每个实例都可以更改它,则该属性不会非常readonly

当然,您可以在构造函数中更改非static readonly个实例成员:

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 - 是的,您需要将它们设为private set - 除非您使用的是后备字段。我提出这个问题的主要原因是因为使用具有私有集的属性将允许您执行代码尝试执行的操作,因为类本身可以在任何方法或构造函数中更改属性(静态或实例),但代码课外不能。

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

答案 1 :(得分:2)

它与public与private无关,而是静态与非静态构造函数。

如果您尝试在非静态构造函数中设置静态只读项(如第二种情况),编译器会抱怨:

  

无法分配静态只读字段(静态除外)   构造函数或变量初始化程序)

这是因为静态成员在第一次访问类型时被初始化,这可能在任何常规构造函数被调用之前。从实例构造函数中修改静态只读成员是没有意义的,因此编译器会对其进行防范。

只需将相关成员设置为非静态或将初始化放入静态构造函数。

答案 2 :(得分:1)

MaximumRecipientsReached是只读的静态,您尝试从非静态构造函数设置它。您只能在静态构造函数中设置它。

答案 3 :(得分:0)

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