原文:https://blogs.msdn.microsoft.com/mazhou/2017/11/21/c-7-series-part-6-read-only-structs/ 背景 在.NET世界中,有兩種基本類型:引用類型和值類型。簡單地說,引用類型是可以繼承/擴展的類,當傳遞引用類型對象時 ...
原文: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 訪問修飾符