【问题标题】:Is there any point to marking a private field readonly?将私有字段标记为只读有什么意义吗?
【发布时间】:2011-10-03 18:12:27
【问题描述】:
public class Foo
{
    private readonly Bar _bar;
}

public class Foo2
{
    private Bar _bar;
}

我认为将其标记为只读没有任何好处。它是私有的,如果我尝试在内部做一些事情来修改它,那是我很愚蠢,因为我知道我希望我的班级如何表现?那么,有什么意义呢?我认为这里没有任何性能提升,所以不可能。

【问题讨论】:

    标签: c# private readonly


    【解决方案1】:

    让编译器防止你变笨总是好的。

    让编译器防止其他人变得愚蠢尤其好,即使他们不熟悉代码库。

    它还可以告诉其他阅读您的代码的人该字段永远不会改变

    【讨论】:

    • 虽然...有时人们会将某些内容标记为只读,只是因为他们当时看不到更改它的理由。然后,当我落后于他们并有正当理由更改它时,我看到“只读”并且我就像“废话......一定有一个重要的原因他们将其标记为只读”,只是浪费我的时间发现那里真的没有其他原因,只是他们当时根本不需要改变它。
    【解决方案2】:

    如果您想在实例化时分配它,但不希望它是可更改的,Readonly 很好。我能想到的一个很好的场景可能是一个带有用户名/密码的数据库类。

    public MyClass(string user, string password){
      this.username = username;
      this.password = password;
      this.connect();
    }
    

    假设在对象处于活动状态的整个期间都保持连接,存储此信息以供参考可能是有意义的,但一旦建立连接就可以防止将来发生更改。

    【讨论】:

      【解决方案3】:

      在你编写这个类的时候,你知道你希望它如何表现。

      但是:

      • 您可能会在第一次编写课程时犯错。
      • 稍后回来修改课程时,您可能不记得自己的意图。
      • 其他程序员稍后修改类时可能不知道您的意图。

      您的声明允许编译器验证您的意图是否得到满足,成本低廉且重复。它会向您和其他人传达您的意图。

      【讨论】:

        【解决方案4】:

        你是对的,没有性能提升。但是,这里有一些关键的区别:

        如果您打算创建一个不尝试修改 _bar 的类,它实际上应该是一个只读字段。我可以在这里看到两件事:

        1. 只读字段只能在内联或构造期间初始化(安全)。
        2. 它可以防止其他程序员出现并认为“哦,它不是只读的。我可以修改它。”

        现在,如果您打算将其保持为空,则它应该 NOT 是只读的,直到调用另一个方法来初始化它。但是,为此我会查看Lazy<T>


        基本上,这是您的决定。如果您真的要成为修改此类的唯一 人,我仍然会说遵循这些规则。这是做到这一点的最佳实践方式。 :)

        【讨论】:

        【解决方案5】:

        它是私有的,如果我尝试在内部做一些事情来修改它,那我就是愚蠢,因为我知道我希望我的班级表现如何?

        如果您是项目历史上唯一一个会查看或修改源代码的人并且您有完美的记忆,那么,是的。不需要 cmets 或其他编程约定。就当牛仔吧。

        否则,使用约定来(重新)执行意图不是一个坏主意。

        【讨论】:

          【解决方案6】:

          假设一个类应该包含一组可变的T,并且它有一个私有字段T[] theArray。可以通过多种方式设置该类:

          1. 该字段可能是对永远不会更改的数组的可变引用;对列表的更改将通过创建一个适当大小的新数组、将数据复制到其中、根据需要对其进行修改,然后将对新数组的引用存储到字段中来完成。请注意,通过将数组包装在“ReadOnlyCollection”中,该类可以廉价地公开数组内容的只读快照;创建快照不需要复制阵列。
          2. 该字段可能是对可变数组的可变引用。大多数更新将通过改变现有数组来完成,但是超出数组末尾的更新将创建一个新的,其中包含从旧数组复制的元素。这就是 `List` 的工作原理。请注意,将数组包装在 `ReadOnlyCollection` 中可能会产生一段时间内表现为实时数据的只读视图,但可能在未来某个任意时间成为当时数据的快照。
          3. 该字段可能是对可变数组的不可变引用,前提是该数组大到足以容纳将要添加的所有内容。可变长度列表不太可能,但在某些应用程序中,为最大项目数预先指定和预先分配空间可能是合理的。在这种情况下,将数组包装在 ReadOnlyCollection 中会产生其状态的实时视图。

          这三种不同的方法对线程安全等事物具有不同的含义。如果将 readref-copy-modify-writeref 序列放置在 Interlocked.CompareExchange 循环中,则第一个可以成为线程安全的。通过使单个元素写入线程安全,可以使最后一个线程安全。然而,第二个只能通过至少让所有写操作共享一个对整个列表来说是通用的锁并要求读者仔细检查他们的操作以确保一致性,或者要求所有读写访问都必须通过一个公共锁。

          【讨论】:

            猜你喜欢
            • 2010-09-21
            • 2014-10-02
            • 1970-01-01
            • 2011-03-03
            • 2021-05-29
            • 2019-05-06
            • 2018-12-24
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多