C# 中的不可变类型和属性
C# 中的不可变类型和不可变属性是什么意思?你能举个简单的例子吗?
What is meant by immutable type and immutable property in C# ? can you give simple example?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不可变类型是其属性只能在初始化时设置的类型。一旦创建了对象,就无法再更改任何内容。不可变属性只是只读属性。
在以下示例中,
ImmutableType
是一种不可变类型,具有一个属性Test
。测试是只读属性。它只能在构造时设置。另请参阅:维基百科文章和一些堆栈 关于该主题的溢出问题。
An immutable type is a type of which its properties can only be set at initialization. Once an object is created, nothing can be changed anymore. An immutable property is simply a read-only property.
In the following example,
ImmutableType
is an immutable type with one propertyTest
. Test is a read-only property. It can only be set at construction.See also: The Wikipedia article, and some Stack Overflow questions on the topic.
除了上面 @fretje 的答案之外,在 C#6 及更高版本中, 仅 getter 自动属性 现已实现,它允许不可变的自动属性,而不需要额外的显式
private readonly
支持场。等效代码将缩写为:请注意,
private set
仅提供对同一类内的属性更改的受限封装,因此并不是真正不可变的:有关不变性的更多信息< /strong>
正如其他人所说,
不可变属性
是一旦设置就无法更改的属性。 “唯一”值的设置是在构造期间完成的。不可变类型
是一种所有(外部可见)属性和字段都是不可变的类型 - 例如最初计划用于 C#7 的“Record”类型 (希望现在是 8) 将是一个不可变类型。不可变类型的其他示例是元组
,以及所有匿名类。在 C# 中,不可变字段应使用 readonly 关键字进行限定 - 这是由编译器强制执行的,以确保没有其他代码尝试更改构造函数之外的字段。
只要有可能,字段、变量和属性的不变性就被认为是良好的实践,因为这大大减少了错误的表面积(因为字段代表对象的状态,防止字段的更改会减少状态的数量)。
不变性的好处在多线程程序中尤其重要,其中两个或多个线程同时访问同一对象。由于多个并发读取线程可以安全地读取字段或属性的值,因此程序员无需担心与其他线程更改字段相关的线程安全问题(因为禁止更改属性)
一个常见的缺点在处理由多个组合对象组成的复杂对象时,不变性的一个重要原因是整个图需要“一次性”构建,这可能会导致代码混乱。这里的一个常见解决方案是使用构建器模式作为脚手架,它允许分步构建瞬态、可变的表示形式,然后在最后的
.Build()
步骤中获得最终的不可变对象。In addition to @fretje's answer above, in C#6 and later, getter-only auto properties have now been implemented, which allows for immutable auto-properties without the need for the additional explicit
private readonly
backing field. The equivalent code would be abbreviated to:Note that
private set
only provides a restricted encapsulation of change to the property from within the same class, and thus isn't truly immutable:More about immutability
As others have said, an
immutable Property
is a property which cannot change once it has been set. Setting of the 'only' value is done during construction.An
immutable Type
is a type where all (externally visible) properties and fields are immutable - for example the "Record" Type originally scheduled for C#7 (hopefully now 8) would have been an immutable type. Other examples of Immutable Types areTuples
, and all anonymous classes.Immutable fields should be qualified with the
readonly
keyword in C# - this is enforced by the compiler to ensure that no other code attempts to change the field outside of the constructor.Wherever possible, immutability of fields, variables and properties is regarded as good practice, as this greatly reduces the surface area for bugs (since fields represent the state of an object, preventing change to fields reduces the number of states).
The benefit of immutability is especially important in multi-threaded programs, where two or more threads concurrently access the same object. Since multiple concurrent reading threads can safely read the value of a field or property, the programmer doesn't need to be concerned about thread safety issues relating to change to the field by other threads (because change to the property is prohibited)
One common drawback of immutability when dealing with complex objects consisting of multiple composed objects, is that the entire graph needs to be built 'in one go', which can lead to messy code. A common solution here is to use the Builder pattern as a scaffold, which allows a transient, mutable representation to be built in steps, and then the final, immutable object is obtained in the final
.Build()
step.弗雷耶是正确的。不可变类型最流行的示例是 C# 中的
string
对象。这就是StringBuilder
存在的全部原因。fretje is correct. The most popular example of an immutable type is a
string
object in C#. This is the entire reason thatStringBuilder
exists.C# 中的不变性没有明确的定义:
它通常要求所有公共字段都是只读的,所有公共属性都具有 init setter 或不具有 setter。
它也可以将其扩展到私有成员(尽管通常使用可变私有成员来缓存值,即哈希码)
这也可能意味着所有成员本身都是不可变类型。否则,消费者仍然可以通过调用成员方法来修改对象
这也可能意味着当使用相同的参数调用时,所有方法总是返回相同的输出。特别是不可变的 GetHashCode() 意味着该对象可以安全地用作字典等中的键
一个更强大且通常更有用的概念是 - 'Data' 是一个不可变类型,它也具有值语义(通常通过继承
IEquatable
)以下是满足上述所有要求的“数据”类型的示例:(
请参阅项目 F 了解有关数据类型如何有用的更多信息)
There is no clear definition for immutability in C#:
It usually entails all public fields to be readonly and all public properties to have init setter or no setter.
It may also extend this to private members (although it is common to use mutable private members to cache values ie the hashcode)
It may also mean all members are themselves of immutable types. As otherwise a consumer can still modify the object by calling a member method
It may also mean all methods always return the same output when called with the same arguments. In particular an immutable GetHashCode() means the object is safe to use as a key in dictionaries etc
A stronger and often more useful concept is that of - 'Data' an Immutable type which also has value semantics (usually by inheriting from
IEquatable<T>
)Here is an example of a 'Data' type that satisfies all of the demands above:
(see project F for more on how Data types are useful)