[英]C# - Why are record classes immutable by default, but record structs are not?
我被告知结构应该几乎总是不可变的,所以记录类与记录结构的这种不寻常行为让我措手不及。
使用一条记录class...
record class Person(string FirstName, string LastName);
Person p = new("John", "Smith");
p.FirstName = "Jack" // Not allowed!
使用记录结构...
record struct Person(string FirstName, string LastName);
Person p = new("John", "Smith");
p.FirstName = "Jack" // Fine!
使用只读记录结构...
readonly record struct Person(string FirstName, string LastName);
Person p = new("John", "Smith");
p.FirstName = "Jack" // Now allowed!
为什么非readonly
记录结构在默认情况下是可变的,为什么相同的行为不适用于记录类?
编辑:我想我在这里问的是,为什么语法......很奇怪?
例如,它看起来更符合逻辑:
record class
- 具有值语义的可变引用类型。readonly record class
- 具有值语义的不可变引用类型。record struct
- 具有值语义的可变值类型。readonly record struct
- 具有值语义的不可变值类型。直接取自 Microsoft MVP 工程师 İlkay İlknur:
大多数生成的代码看起来类似于记录类。 但是,记录结构和记录类之间存在一个区别。 记录结构中生成的属性默认是可变的。 这个决定背后的原因是与元组一致。 元组就像具有相似特征的匿名记录结构。 另一方面,结构可变性并不像类可变性那样受到关注。 这就是 C# 团队决定让记录结构属性默认可变的原因。 但是,如果您需要不可变的记录结构,则可以使用 readonly 关键字。
如果您使用位置语法来定义record class
,它的属性是不可变的
record class Point(int X, int Y);
它默认具有{get; init;}
的属性附件{get; init;}
如果您以传统方式声明它(没有位置参数),您可以指定您的属性访问器:
record class Point
{
int X {get; set;}
int Y {get; set;}
}
您可以混合搭配这两个 styles,但请记住,如果您提供任何位置参数,它们将成为自动实现的构造函数的参数,并且不会设置任何其他属性。
我意识到这实际上并没有回答为什么存在这种行为的问题,我只是希望阅读本文的人不会得出record class
是不可变的结论。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.