【问题标题】:C# modification of read-only field via referenceC#通过引用修改只读字段
【发布时间】:2013-09-01 16:43:21
【问题描述】:

我来自 C++,非常怀念 C# 中的“const”。

我在我的代码中发现了一个令人讨厌的错误,请考虑一下:

class MyClass {
    BitArray myFlags { get; private set; } // this should not be able to be manipulated from outside

    // ... constructor here creating the BitArray ...
}

// ...

MyClass foo = new MyClass();

BitArray bar = foo.myFlags;
bar.SetAll(false); // circumvents encapsulation eventually putting the class in inconsitent state

用户可以毫无问题地改变我的对象的状态。 如何安全地公开一个类的成员,而不让用户有机会操纵我的对象的状态?在提供对该成员的公共(读取)访问权限时,我是否必须“.clone()”每个基于引用的成员(基本上是所有内容)?

我想要实现的是适当的封装。当用户创建我的类的实例并读取成员时,我希望保护该成员不被写入,除非它也有一个公共设置器。

【问题讨论】:

  • readonly 不会影响字段指向的实例。 C# 还没有语言级别的不变性。
  • 如何将myFlags 设为私有并编写自己的get/set 方法,在其中检查一致性?
  • @Corak 遗憾的是这并没有改变任何东西。即使您将其设为私有并创建一个 getter(我的班级的用户应该能够以某种形式检查标志),用户仍将设法获得参考,然后尽管有所有隐私,但仍可以修改状态。
  • 虽然并不总是合适的。我想说尽量不要暴露任何内部状态,而只是操作。如果在您的示例中 BitArray 不仅仅是一个实现细节,并且您的类的用户应该有权访问所有/许多(非变异)BitArray 方法,您可以返回它的副本,或者编写一个包装器它只公开那些方法。

标签: c# memory-leaks class-design encapsulation


【解决方案1】:

C# 提供 ReadOnlyCollection 作为不可变集合的选项。

希望对你有帮助!

【讨论】:

    猜你喜欢
    • 2018-05-28
    • 2017-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-09
    • 2019-09-18
    • 1970-01-01
    • 2012-06-04
    相关资源
    最近更新 更多