为啥在更改的字段上使用只读修饰符?

Posted

技术标签:

【中文标题】为啥在更改的字段上使用只读修饰符?【英文标题】:Why use a readonly modifier on a field that changes?为什么在更改的字段上使用只读修饰符? 【发布时间】:2016-05-10 07:56:56 【问题描述】:

在 Josh Smith 的 this 教程中,字段被定义为只读:

    public class CustomerRepository
    

    readonly List<Customer> _customers;
    ...
    public CustomerRepository(string customerDataFile)
    
        _customers = LoadCustomers(customerDataFile);
    
    ...
    

稍后更新只读列表_customers

    public void AddCustomer(Customer customer)
    
        if (customer == null)
            throw new ArgumentNullException("customer");

        if (!_customers.Contains(customer))
        
            _customers.Add(customer);

            if (this.CustomerAdded != null)
                this.CustomerAdded(this, new CustomerAddedEventArgs(customer));
        
    

这是如何被允许的,使用只读有什么意义?

【问题讨论】:

【参考方案1】:

List&lt;Customer&gt; 变量本身 (_customers) 是 readonly - 这意味着您不能将其切换到完全不同的列表,以确保查看它的每个人都会看到相同的列表。但是,您仍然可以更改该列表的元素。

【讨论】:

如果它是一个对象,我可以为其属性设置新值吗? @Saeid 是的 - 你没有修改变量的值,所以你没有违反 readonly 修饰符。【参考方案2】:

来自 MSDN (https://msdn.microsoft.com/en-us/library/acdd6hb7.aspx):

readonly 关键字是可用于字段的修饰符。当字段声明包含readonly 修饰符时,由声明引入的对字段的赋值只能作为声明的一部分或在同一类的构造函数中出现

您无法为 _customers 字段分配新值,但您仍会更改该列表中的元素。

【讨论】:

【参考方案3】:

_customers.Add(customer); 不更新列表。该运算符更新列表的内容。如果你想更新列表,你必须使用_customers= ... 之类的东西。 readonly

可以防止这种情况发生

【讨论】:

【参考方案4】:

使字段只读的关键是不能更改引用。这意味着你不能写类似的东西

_customers = null;

_customers = new List<Customer>();

调用方法.Add()通过方法访问集合,并不会改变对象的引用。

这对于防止任何 NullReferenceException 很有用。

【讨论】:

以上是关于为啥在更改的字段上使用只读修饰符?的主要内容,如果未能解决你的问题,请参考以下文章

为啥Java限制隐藏方法的访问修饰符[关闭]

第六章类属性3提供属性验证只读和只写属性取值和赋值方法的访问修饰符

为啥 Java 反射 API 允许我们访问私有和受保护的字段和方法?这不会破坏访问修饰符的目的吗? [复制]

“公共只读”访问修饰符?

为啥视图修饰符不能接受不可变变量?

typescript 具有只读修饰符的类