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

系列文章:

[译]C# 7系列,Part 6: Read-only structs 只读结构的更多相关文章

  1. [译]C# 7系列,Part 9: ref structs ref结构

    原文:https://blogs.msdn.microsoft.com/mazhou/2018/03/02/c-7-series-part-9-ref-structs/ 背景 在之前的文章中,我解释了 ...

  2. [译]C# 7系列,Part 8: in Parameters in参数

    原文:https://blogs.msdn.microsoft.com/mazhou/2018/01/08/c-7-series-part-8-in-parameters/ 背景 默认情况下,方法参数 ...

  3. [译]C# 7系列,Part 2: Async Main 异步Main方法

    原文:https://blogs.msdn.microsoft.com/mazhou/2017/05/30/c-7-series-part-2-async-main/ 你大概知道,C#语言可以构建两种 ...

  4. [译]C# 7系列,Part 3: Default Literals 默认文本表达式

    原文:https://blogs.msdn.microsoft.com/mazhou/2017/06/06/c-7-series-part-3-default-literals/ C#的default ...

  5. [译]C# 7系列,Part 4: Discards 弃元

    原文:https://blogs.msdn.microsoft.com/mazhou/2017/06/27/c-7-series-part-4-discards/ 有时我们想要忽略一个方法返回的值,特 ...

  6. [译]C# 7系列,Part 5: private protected 访问修饰符

    原文:https://blogs.msdn.microsoft.com/mazhou/2017/10/05/c-7-series-part-5-private-protected/ C#有几个可访问性 ...

  7. [译]C# 7系列,Part 7: ref Returns ref返回结果

    原文:https://blogs.msdn.microsoft.com/mazhou/2017/12/12/c-7-series-part-7-ref-returns/ 背景 有两种方法可以将一个值传 ...

  8. [译]C# 7系列,Part 10: Span<T> and universal memory management Span<T>和统一内存管理

    原文:https://blogs.msdn.microsoft.com/mazhou/2018/03/25/c-7-series-part-10-spant-and-universal-memory- ...

  9. [译]C# 7系列,Part 1: Value Tuples 值元组

    Mark Zhou写了很不错的一系列介绍C# 7的文章,虽然是2年多年前发布的,不过对于不熟悉C# 7特性的同学来说,仍然有很高的阅读价值. 原文:https://blogs.msdn.microso ...

随机推荐

  1. Ztree树增删改查菜单,遇到的问题总结

    一.引言 我今天做了一个Ztree树增删改查菜单的功能.其中遇到了很多坑爹的问题,和大家讲述一下. 二.代码展示 1.Ztree树前台代码 <%@ page language="jav ...

  2. 【Android - 自定义View】之MeasureSpec简介

    MeasureSpec是View测量过程中的一个重要的类,它被用来将View的尺寸规格(SpecSize)和尺寸模式(SpecMode)封装在一起,并提供打包和解包的方法. MeasureSpec虽然 ...

  3. AutoCAD二次开发(2020版)--4,使用ARX向导创建编程模板(框架)--

    手动创建ObjectARX应用程序非常麻烦,在此步骤中,将介绍ObjectARX向导. 在这里,我们将使用ObjectARX向导创建我们的ObjectARX应用程序. 本节的程序的需求是,接收CAD用 ...

  4. C语言I作业10

    问题 回答 这个作业属于哪个课程 C语言程序设计II 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/SE2019-2/homework/10100 我在 ...

  5. MQTT版本升级过程及源码解析

    MQTT版本升级过程及源码解析 首先说一下为什么要写这篇文章呢,在我发现网上对MQTT的文章介绍实在太少了,可能也是使用这个的频率比较低吧!还有对问题的定位以及解决的方式和办法也太少了,所以特意写这篇 ...

  6. 自动列表排序.html

    li:before { content: counter(chapter) ". "; counter-increment: chapter; font-weight: bold; ...

  7. 洛谷 题解 P3173 【[HAOI2009]巧克力】

    本蒟蒻又双叒叕被爆踩辣! 又是一道经典的贪心题: 那么怎样切割该块巧克力,花费的代价最少呢? Solution: 窝们考虑每个状态,有多少种选择方法? 是不是可以选择横着切或者竖着切,就这两种方法吧: ...

  8. Spring代理模式(jdk动态代理模式)

    有动态代理和静态代理: 静态代理就是普通的Java继承调用方法. Spring有俩种动态代理模式:jdk动态代理模式 和 CGLIB动态代理 jdk动态代理模式: 代码实现: 房东出租房子的方法(继承 ...

  9. Geoserver2.15.1 配置自带 GeoWebCache 插件发布 ArcGIS Server 瓦片(附配置好的 Geoserver2.15.1 下载)

    之前写过一篇关于 Geoserver2.8.5 版本的部署配置发布 ArcGIS Server 瓦片点击查看,那是下载 Geoserver2.8.5 源码编译,重新打包 jar 来部署配置思路的,版本 ...

  10. POJ2528---Mayor's posters

    The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign h ...