[英]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.