原文:https://blogs.msdn.microsoft.com/mazhou/2017/11/21/c-7-series-part-6-read-only-structs/
背景
在.NET世界中,有兩種基本類型:引用類型和值類型。簡單地說,引用類型是可以繼承/擴展的類,當傳遞引用類型對象時,傳遞的是一個“指針”;值類型是不能繼承/擴展的結構,當傳遞值類型對象時,傳遞的是一個“副本”。
C#中的struct是一個值類型,它“內部繼承”自System.ValueType。(我說的是結構之間沒有繼承。)
當在參數中使用struct時,會生成struct的副本,使用struct可能是高效的,因為它減少了堆對象分配的時間。
在許多場景中,開發人員使用結構作為傳遞值的有效方法,例如方法的返回對象,或者跨應用程序使用的基本數據結構。
只讀結構
只讀結構是其公共成員為只讀的結構,就好像“this”變量一樣。
看一下下面的聲明:
public struct S { public int Age { get; set; } public string Name { get; set; } public S(int age, string name) { this.Age = age; this.Name = name; } public S(S other) { this = other; } public S Replace(S other) { S value = this; this = other; return value; } }
可以看到,我可以完全訪問已聲明的屬性Age和Name,還可以訪問this變量,這樣就可以用另一個實例S來替換this實例。
如果我在聲明中添加readonly修飾符,我的訪問權限將受到限制:
- 所有的成員(屬性、字段)必須是自讀;
- 我需要在公共的有參構造函數中初始化成員;
- 除了在構造函數中,“this”變量在其他地方都是只讀的;
- 你不能定義“類字段”事件;
下面的截圖顯示了上面的代碼改成了readonly struct后需要修正的地方。
下面是修改后的代碼:
public readonly struct S { public int Age { get; } public string Name { get; } public S(int age, string name) { this.Age = age; this.Name = name; } public S(S other) { this = other; } }
你可以像往常一樣初始化S的新實例。但是你不能修改任何實例的任何成員。你應該總是調用有參(而不是無參)構造函數來正確初始化實例對象,否則您將獲得實例的默認值(所有成員都被初始化為成員類型的默認值)。
private static void Test() { S s = new S(18, "Anna"); ref S other = ref s; other = new S(other); bool equal = s.Equals(other); // true. }
結論
只讀結構是一個方便的特性,可以幫助保護你的值被意外修改的影響;與其他新特性相結合(例如,ref結構和in參數),它將使你的C#代碼更容易地面向低級別的編程。在接下來的幾篇文章中,我將解釋所有這些新事物。請注意,你需要C# 7.2才能使用這個特性,它在Visual Studio 2017.5 Preview 4或更高版本中可用。
系列文章:
- [譯]C# 7系列,Part 1: Value Tuples 值元組
- [譯]C# 7系列,Part 2: Async Main 異步Main方法
- [譯]C# 7系列,Part 3: Default Literals 默認文本表達式
- [譯]C# 7系列,Part 4: Discards 棄元
- [譯]C# 7系列,Part 5: private protected 訪問修飾符
- [譯]C# 7系列,Part 6: Read-only structs 只讀結構 (本文)
- [譯]C# 7系列,Part 7: ref Returns ref返回結果
- [譯]C# 7系列,Part 8: in Parameters in參數
- [譯]C# 7系列,Part 9: ref structs ref結構
- [譯]C# 7系列,Part 10: Span<T> and universal memory management Span<T>和統一內存管理 (完)