原文: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(, "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或更高版本中可用。

系列文章:

最新文章

  1. ctype.h库函数----字符操作函数
  2. LeetCode:Longest Palindromic Substring 最长回文子串
  3. remove all .git files and directories use one command
  4. NOIP2001 一元三次方程求解
  5. Oracle11.2.0.4 RAC安装文档
  6. poj 3624 Charm Bracelet(区间dp)
  7. LeetCode 319. Bulb Switcher
  8. $.ajax({})方法success,error,complete,beforeSend使用例子及解释
  9. 状态机/迭代器/LINQ/协程
  10. .net js有数据 但是跳转不到操作页
  11. MYSQL后更改ROOT的密码后无法启动服务报错1067
  12. 老男孩python学习自修第四天【字典的使用】
  13. swift class的动态派发
  14. Java 9 揭秘(1. 入门介绍)
  15. 关于ManyToMany的一点补充
  16. php中strpos()函数
  17. iOS 使用UI控件的外观协议UIAppearance进行设置默认UI控件样式
  18. Java执行CMD命令
  19. 转 : Apache启动报错:could not bind to address [::]:443 解决办法
  20. 【HEOI 2018】林克卡特树

热门文章

  1. [转载] Docker 实现原理
  2. Head First设计模式——模板方法模式
  3. 页面嵌套iframe的时候引发的js交互问题
  4. HC大会,华为联合合作伙伴发布一站式物联网IoT开发工具小熊派BearPi
  5. CarbonData:大数据融合数仓新一代引擎
  6. 最新Navicat Premium12 破解方法,亲测可用
  7. luogu P1951 收费站_NOI导刊2009提高(2) |二分答案+最短路
  8. luogu P1850 换教室
  9. Xcode 清理存储空间(转)
  10. BZOJ 3108: [cqoi2013]图的逆变换