C#中的只读结构体(readonly struct)详解

 更新时间:2020年11月02日 11:59:42   作者:技术译民  
这篇文章主要给大家介绍了关于C#中只读结构体(readonly struct)的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

翻译自 John Demetriou 2018年4月8日 的文章 《C# 7.2 – Let's Talk About Readonly Structs》[1]

在本文中,我们来聊一聊从 C# 7.2 开始出现的一个特性 readonly struct。

任一结构体都可以有公共属性、私有属性访问器等等。我们从以下结构体示例来开始讨论:

public struct Person
{
 public string Name { get; set; }

 public string Surname { get; set; }

 public int Age { get; set; }

 public Person(string name, string surname, int age)
 {
 Name = name;
 Surname = surname;
 Age = age;
 }

 public void Replace(Person other)
 {
 this = other;
 }
}

如您所见,所有属性都可以公开访问和修改。更糟糕的是,我们甚至可以访问 this (通过调用 Replace 方法),将其更改为同一结构体类型的另一个实例。

这就是 readonly 关键字出现的原因。如果(仅)在结构体的定义中添加它,如下所示:

public readonly struct Person
{
 public string Name { get; set; }

 public string Surname { get; set; }

 public int Age { get; set; }

 public Person(string name, string surname, int age)
 {
 Name = name;
 Surname = surname;
 Age = age;
 }

 public void Replace(Person other)
 {
 this = other;
 }
}

编译器会显示如下面截图中的错误提示:

为什么会这样?这是因为当我们向结构体定义添加 readonly 关键字,其实是把每个属性都设置为只读的了,包括 this 的值。

要让代码通过编译的唯一方法是把所有内容都设置为只读的,也就是说我们的结构体应该像这样:

public readonly struct Person
{
 public string Name { get; }

 public string Surname { get; }

 public int Age { get; }

 public Person(string name, string surname, int age)
 {
 Name = name;
 Surname = surname;
 Age = age;
 }
}

因此,添加 readonly 可以消除结构体实例内部或外部发生意外赋值或修改值的可能性。不过,需要注意的一件事是,如果您经常使用无参构造函数并给属性赋值,像这样:

Person s = new Person();
//错误
s.Age = 15;
s.Name = "asd";
s.Surname = "qwe";

或者像这样:

//错误
Person s = new Person
{
 Age = 15,
 Name = "asd",
 Surname = "qwe"
};

虽然此结构体的默认无参构造函数仍然可以调用,但给任何属性赋值都将引发编译错误,因为属性是只读的。
实际上,对此结构体的无参构造函数的调用会将其所有属性设置为它们的默认值,而且在结构体实例的整个生命周期中,永远不会被修改。

正确的初始化方法是调用参数化构造函数:

Person s = new Person("asd", "qwe", 15);

总之,这将有助于更容易地表明您的意图,因为您可以从一开始就定义这个结构体是不可变和不可修改的。

译者总结

使用 readonly 修饰符声明 struct 的目的就是为了明确地声明一个不可变的值类型。

readonly 结构体的所有数据成员都必须是只读的:

  • 所有字段声明都必须具有 readonly 修饰符
  • 所有属性(包括自动实现的属性)都必须是只读的

这就保证了 readonly 结构体的成员不会修改该结构体的状态。在 C# 8.0 及更高版本中,除构造函数外的其他实例成员都是隐式 readonly 的。

到此这篇关于C#中只读结构体(readonly struct)详解的文章就介绍到这了,更多相关C#只读结构体(readonly struct)内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关链接:

https://www.devsanon.com/c/c-7-2-lets-talk-about-readonly-structs/ C# 7.2 – Let's Talk About Readonly Structs ↩︎

www.jb51.net/article/195539.htm C# 中 Struct 和 Class 的区别总结 ↩︎

相关文章

  • C#将字母或数字加密成字母的方法

    C#将字母或数字加密成字母的方法

    这篇文章主要介绍了C#将字母或数字加密成字母的方法,涉及C#操作字符串的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-03-03
  • C#实现集合自定义排序的三种方式

    C#实现集合自定义排序的三种方式

    在C#中,集合排序是一种常见的操作,它可以帮助我们对集合中的元素进行排序,C#中提供了多种集合排序方法,包括Array.Sort、List.Sort、SortedList和SortedSet等,本文给大家介绍了C#实现集合自定义排序的三种方式,需要的朋友可以参考下
    2025-01-01
  • C#使⽤XmlReader和XmlWriter操作XML⽂件

    C#使⽤XmlReader和XmlWriter操作XML⽂件

    这篇文章介绍了C#使⽤XmlReader和XmlWriter操作XML⽂件的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • C#中Trim()、TrimStart()、TrimEnd()的用法介绍

    C#中Trim()、TrimStart()、TrimEnd()的用法介绍

    这篇文章主要介绍了C#中Trim()、TrimStart()、TrimEnd()的用法,有需要的朋友可以参考一下
    2014-01-01
  • C# SetWindowPos函数实例详解

    C# SetWindowPos函数实例详解

    在C#中,SetWindowPos函数用于设置窗口的位置和大小,这篇文章主要介绍了C# SetWindowPos函数实例详解,本文给大家介绍的非常详细,需要的朋友可以参考下
    2024-03-03
  • 基于C#设计一个双色球选号工具

    基于C#设计一个双色球选号工具

    这篇文章主要为大家详细介绍了如何利用C#设计实现一个双色球选号工具,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • Unity实现多平台二维码扫描

    Unity实现多平台二维码扫描

    这篇文章主要为大家详细介绍了Unity实现多平台二维码扫描,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07
  • C# winform程序读取文本中的值实例讲解

    C# winform程序读取文本中的值实例讲解

    在本篇文章中小编给大家分享了关于C# winform程序读取文本中的值的相关知识点,有兴趣的朋友们学习下。
    2019-06-06
  • 一道关于C#参数传递的面试题分析

    一道关于C#参数传递的面试题分析

    这篇文章主要介绍了一道关于C#参数传递的面试题,实例分析了C#参数传递的相关使用技巧,需要的朋友可以参考下
    2015-05-05
  • C# webservice接口编写、发布与测试

    C# webservice接口编写、发布与测试

    这篇文章主要介绍了C# webservice接口编写、发布与测试,文章通过图文结合的方式给大家介绍的非常详细,对大家的学习或共组有一定的帮助,需要的朋友可以参考下
    2024-07-07

最新评论