C#中的不可变类型和属性

C#中的不可变类型和不可变属性是什么意思? 你能举一个简单的例子吗?

不可变类型是一种只能在初始化时设置其属性的类型。 创建对象后,就不能再进行任何更改。 不可变属性只是一个只读属性。

在以下示例中, ImmutableType是一个具有一个属性Test的不可变类型。 Test是一个只读属性。 它只能在施工时设置。

 class ImmutableType { private readonly string _test; public string Test { get { return _test; } } public ImmutableType(string test) { _test = test; } } 

另请参阅 : Wikipedia文章以及有关该主题的一些Stack Overflow问题 。

弗雷特是对的。 不可变类型最流行的例子是C#中的string对象。 这就是StringBuilder存在的全部原因。

除了@ fretje上面的答案之外,在C#6及更高版本中,现在已经实现了仅具有getter的自动属性 ,这允许不可变的自动属性,而无需额外的显式private readonly备份字段。 等效代码将缩写为:

 class ImmutableType { public string Test { get; // No Set at all, not even a private set. } public ImmutableType(string test) { Test = test; // The compiler understands this and initializes the backing field } } 

请注意, private set (最接近不变性可能在早期版本的C#中使用自动属性)仅在同一个类中提供对属性的更改的受限封装,因此不是真正不可变的:

 public string Test { get; private set; // Not immutable, since this is still mutable from within the class } 

更多关于不变性

正如其他人所说, immutable Property是一旦设定就无法改变的财产。 “唯一值”的设置通常在构造函数中完成。

immutable Type是一种类型,其中所有(外部可见)属性和字段都是不可变的 – 例如,最初为C#7 (希望现在为8)安排的“记录”类型将是不可变类型。 不可变类型的其他示例是Tuples和所有匿名类 。

不可变字段应该使用C#中的readonly关键字进行限定 – 这是由编译器强制执行的,以确保没有其他代码尝试更改构造函数之外的字段。

在可能的情况下,字段,变量和属性的不变性被视为良好实践,因为这极大地减少了错误的表面区域(因为字段表示对象的状态,防止对字段的更改减少了状态的数量)。

不可变性的好处在multithreading程序中尤其重要,其中两个或多个线程同时访问同一对象。 由于多个并发读取线程可以安全地访问字段或属性的值,因此程序员不需要关心与其他线程对字段的更改有关的线程安全问题。

处理由多个组合对象组成的复杂对象时,不可变性的一个共同缺点是整个图形需要“一次性”构建,这可能导致代码混乱。 这里常见的解决方案是使用Builder模式作为脚手架,它允许在步骤中构建瞬态,可变表示,然后在最终的.Build()步骤中获得最终的不可变对象。