保证 C# 中的不变性
Guaranteeing immutability in c#
在阅读了很多有关 C# 中的不变性并了解它的好处(无副作用、安全字典键、多线程...)之后,我想到了一个问题:
为什么 C# 中没有关键字来断言 class(或结构)是不可变的?该关键字应在编译时检查您无法改变 class(或结构)。例如:
public immutable class MyImmutableClass
{
public readonly string field;
public string field2; //This would be a compile time error
public readonly AnyMutableType field3; //This would be a compile time error
public string Prop { get; }
public string Prop2 { get; set; } //This would be a compile time error
public AnyMutableType Prop3 { get; } //This would be a compile time error
}
我认为编译器的工作会很简单,因为它只需要检查几件事:
- 所有 public 字段都是只读的。
- 所有 public 属性只有吸气剂。
- 所有 public 字段或属性也具有不可变类型(简单值类型或不可变 classes/structs)。
- 所有 public 函数或 public 属性 getter 仅依赖于不可变字段或属性(public fields/props 如前所述,或私有 fields/props 遵守相同的限制)。这当然包括Equals()、GetHashCode()和ToString()。
我想到了这个设计的一些可能问题:
- 为了让编译器知道编译后的 class/struct 是不可变的,可能需要对中间语言进行更改。
- 只读泛型集合(例如
IEnumerable<T>
)不变性将取决于类型<T>
的不变性。建议的 immutable
关键字在此上下文中没有用,因为您不能声明 IEnumerable<string>
是不可变的,即使它是。
前面说的这些理由是否足以让这个关键字不存在?
我是否遗漏了任何其他缺点?
对于语言的如此大的变化,这还不够吗?
简短的版本是:因为没有人提出、规范、设计、实施、测试、记录、翻译和支持该功能。
更长的版本将涉及 为什么 这样做,因为它可以通过 readonly
字段间接实现 - 好处 会加吗
对于类,结果是相对轻微。请注意,有一个 可以 使用的 [ImmutableObject(true)]
属性,但没有任何功能或框架真正使用它,所以......没有人使用它。
提议在未来的 C# 版本中添加 "readonly structs"(与 ref
局部变量、Span<T>
等相关) - 但是:它死了,蒸发了。但是,ref readonly
内容继续存在,旨在防止在 struct
实例方法中重新分配 this
。
在阅读了很多有关 C# 中的不变性并了解它的好处(无副作用、安全字典键、多线程...)之后,我想到了一个问题:
为什么 C# 中没有关键字来断言 class(或结构)是不可变的?该关键字应在编译时检查您无法改变 class(或结构)。例如:
public immutable class MyImmutableClass
{
public readonly string field;
public string field2; //This would be a compile time error
public readonly AnyMutableType field3; //This would be a compile time error
public string Prop { get; }
public string Prop2 { get; set; } //This would be a compile time error
public AnyMutableType Prop3 { get; } //This would be a compile time error
}
我认为编译器的工作会很简单,因为它只需要检查几件事:
- 所有 public 字段都是只读的。
- 所有 public 属性只有吸气剂。
- 所有 public 字段或属性也具有不可变类型(简单值类型或不可变 classes/structs)。
- 所有 public 函数或 public 属性 getter 仅依赖于不可变字段或属性(public fields/props 如前所述,或私有 fields/props 遵守相同的限制)。这当然包括Equals()、GetHashCode()和ToString()。
我想到了这个设计的一些可能问题:
- 为了让编译器知道编译后的 class/struct 是不可变的,可能需要对中间语言进行更改。
- 只读泛型集合(例如
IEnumerable<T>
)不变性将取决于类型<T>
的不变性。建议的immutable
关键字在此上下文中没有用,因为您不能声明IEnumerable<string>
是不可变的,即使它是。
前面说的这些理由是否足以让这个关键字不存在? 我是否遗漏了任何其他缺点? 对于语言的如此大的变化,这还不够吗?
简短的版本是:因为没有人提出、规范、设计、实施、测试、记录、翻译和支持该功能。
更长的版本将涉及 为什么 这样做,因为它可以通过 readonly
字段间接实现 - 好处 会加吗
对于类,结果是相对轻微。请注意,有一个 可以 使用的 [ImmutableObject(true)]
属性,但没有任何功能或框架真正使用它,所以......没有人使用它。
提议在未来的 C# 版本中添加 "readonly structs"(与 ref
局部变量、Span<T>
等相关) - 但是:它死了,蒸发了。但是,ref readonly
内容继续存在,旨在防止在 struct
实例方法中重新分配 this
。