保证c#的不变性

Guaranteeing immutability in c#

在阅读了大量关于C中不可变的内容,并理解了它的好处(没有副作用、安全字典键、多线程……)之后,我想到了一个问题:

为什么在C中没有关键字来断言类(或结构)是不可变的?这个关键字应该在编译时检查您是否无法改变类(或结构)。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
}

我认为编译器的工作会很容易,因为它只需要检查一些东西:

  • 所有公共字段都是只读的。
  • 所有公共属性都只有getter。
  • 所有公共字段或属性也都有不可变的类型(简单值类型或不可变的类/结构)。
  • 所有公共函数或公共属性获取程序只依赖于不可变的字段或属性(如前所述的公共字段/属性,或符合相同限制的私有字段/属性)。这当然包括equals()、getHashCode()和toString()。

这种设计可能会出现一些问题:

  • 为了让编译器知道编译的类/结构是不可变的,可能需要更改中间语言。
  • 只读泛型集合(如IEnumerable不可变)取决于类型的不可变。建议使用的immutable关键字在此上下文中不会有用,因为您不能声明IEnumerable是不可变的,即使它是不变的。

前面所述的原因是否足以使此关键字不存在?我还有其他缺点吗?对语言的如此大的变化来说,这还不够必要吗?


简短的版本是:因为没有人提出、规范化、设计、实现、测试、记录、翻译和支持这个特性。

如果可以通过readonly字段间接实现,那么更长的版本将与为什么要这样做相关——它会带来什么好处。

对于班级来说,这是相对次要的。注意,有一个[ImmutableObject(true)]属性可以使用,但是没有任何特性或框架真正可以使用它,所以…没有人使用它。

有人提议在未来版本的c(与ref当地人、Span等有关)中添加"只读结构",但:它死了,蒸发了。然而,ref readonly的东西仍然存在,这是为了防止struct实例方法中this的重新分配。