c# - 不可变类型可以改变它的内部状态吗?

标签 c# immutability

问题很简单。可以更改其内部状态而无需从外部观察到的类型是否可以被视为不可变

简化示例:

public struct Matrix
{
    bool determinantEvaluated;
    double determinant;

    public double Determinant 
    {
         get //asume thread-safe correctness in implementation of the getter
         {
             if (!determinantEvaluated)
             {
                  determinant = getDeterminant(this);
                  determinantEvaluated = true;
             }

             return determinant;    
         }
    }
}

更新:澄清了线程安全问题,因为它会导致分心。

最佳答案

视情况而定。

如果您正在为客户端代码的作者编写文档或作为客户端代码的作者进行推理,那么您关心的是组件的接口(interface)(即它的外部可观察状态和行为)而不是它的实现细节(比如内部表示)。

从这个意义上说,一个类型是不可变的,即使它缓存了状态,即使它延迟初始化等等——只要这些变化在外部是不可观察的。换句话说,如果一个类型在通过其公共(public)接口(interface)(或其其他预期用例,如果有的话)使用时表现为不可变,则该类型是不可变的。

当然,这可能很难做到正确(内部状态可变,您可能需要关注线程安全、serialization/marshaling behavior 等)。但假设您做对了(至少在您需要的范围内),没有理由考虑这种类型不可变。

显然,从编译器或优化器的角度来看,这种类型通常不被认为是不可变的(除非编译器足够智能或有一些“帮助”,如提示或某些类型的先验知识)和任何优化如果是这种情况,用于不可变类型的可能不适用。

关于c# - 不可变类型可以改变它的内部状态吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31722181/

相关文章:

c# - 为什么我不能有一个不安全的 volatile 指针,只能在 AdHoc 模式下?

c# - 无法使用绑定(bind)源刷新数据 GridView

javascript - Immutable.js 的实际案例是什么?

c# - 如何评估此字符串串联?

c# - C# 中的德语字母和编码

c# - 使用基于 DLR 的语言而不是 C# 来执行脚本任务的原因是什么?

c# - 用 C# 替换\\

design-patterns - 在D中实现值对象模式

scala - 在 2.8.x 中的 Scala 中管理灵活、类型化、不可变的数据结构

c# - 创建单元测试以确保不变性