4

有这样的代码:

    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

4 回答 4

13

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

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

// public getters, private setters...
public static bool MaximumRecipientsReached { get; private set; }
public static IList<EmailAddress> Contacts { get; private set; }
于 2012-07-05T13:42:31.627 回答
2

它与公共与私有无关,而是静态与非静态构造函数。

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

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

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

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

于 2012-07-05T13:43:07.220 回答
1

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

于 2012-07-05T13:43:16.993 回答
0

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

于 2012-07-05T13:45:39.737 回答