C# 中 Struct 和 Class 的区别总结

翻译自 Manju lata Yadav 2019年6月2日 的博文 《Difference Between Struct And Class In C#》,补充了一些内容和示例。

结构体(struct)是类(class)的轻量级版本。结构体是值类型,可用于创建行为类似于内置类型的对象。

比较

结构体和类共享许多特性,但与类相比有以下局限性。

  • 结构体不能有默认构造函数(无参构造函数)或析构函数,构造函数中必须给所有字段赋值。

      public struct Coords{public double x;public double y;public Coords() //错误,不允许无参构造函数{this.x = 3;this.y = 4;}public Coords(double x) //错误,构造函数中必须给所有字段赋值{this.x = x;}public Coords(double x) //这个是正确的{this.x = x;this.y = 4;}public Coords(double x, double y) //这个是正确的{this.x = x;this.y = y;}}
    
  • 结构体是值类型,在赋值时进行复制。

  • 结构体是值类型,而类是引用类型。

  • 结构体可以在不使用 new 操作符的情况下实例化。例如:

      public struct Coords{public double x;public double y;}static void Main(){Coords p;p.x = 3;p.y = 4;Console.WriteLine($"({p.x}, {p.y})");  // 输出: (3, 4)}
    
  • 结构体不能继承于另一个结构体或者类,类也不能继承结构体。所有结构体都直接继承于抽象类 System.ValueTypeSystem.ValueType 又继承于 System.Object

  • 结构体不能是基类,因此,结构体不能是 abstract 的,且总是隐式密封的(sealed)。

  • 不允许对结构体使用抽象(abstract)和密封(sealed)修饰符,也不允许对结构体成员使用 protected 或 protected internal 修饰符。

  • 结构体中的函数成员不能是抽象的(abstract)或虚的(virtual),重写(override)修饰符只允许重写从 System.ValueType 继承的方法。

  • 结构体中不允许实例属性或字段包含初始值设定项。但是,结构体允许静态属性或字段包含初始值设定项。例如:

      public struct Coords{public double x = 4; //错误, 结构体中初始化器不允许实例字段设定初始值public static double y = 5; // 正确public static double z { get; set; } = 6; // 正确}
    
  • 结构体可以实现接口。

  • 结构体可以用作 nullable type(即:Nullable<T> 中的 T),对其赋值 null 值,参考【Nullable<T> Struct (https://docs.microsoft.com/en-us/dotnet/api/system.nullable-1?view=netcore-3.1)】

什么时候使用结构体或类?

要回答这个问题,我们应该很好地理解它们的差异。

序号结构体(struct类(class)
1结构体是值类型,可以在栈(stack)上分配,也可以在包含类型中内联分配。类是引用类型,在堆(heap)上分配并垃圾回收。
2值类型的分配和释放通常比引用类型的分配和释放更节约成本。大的引用类型的赋值比大的值类型的赋值成本更低。
3在结构体中,每个变量都包含自己的数据副本(ref 和 out 参数变量除外),对一个变量的操作不会影响另一个变量。在类中,两个变量可以包含同一对象的引用,对一个变量的任何操作都会影响另一个变量。

这样,结构体(struct)只能在确定以下情形时使用:

  • 它在逻辑上表示单个值,比如基本类型(intdouble,等等)。

  • 它是不可变的(immutable)。

  • 它不会频繁地装箱和拆箱。

在所有其他情形,应该将类型定义为类(class)。

结构体示例:

struct Location
{public int x, y;public Location(int x, int y){this.x = x;this.y = y;}
}static void Main()
{Location a = new Location(20, 20);Location b = a;a.x = 100;Console.WriteLine(b.x);
}

输出将是 20。“b” 的值是 “a” 的副本,因此 “b” 不受 “a.x” 更改的影响。但是在类中,输出将是 100,因为变量 “a” 和 “b” 引用同一个对象。

以下为译者补充

结构体实例与类实例

结构体实例的内存在栈(stack)上进行分配,所占用的内存随声明它的类型或方法一起回收。这就是在赋值时要复制结构体的一个原因。相比之下,类实例的内存在堆(heap)上进行分配,当对类实例的所有引用都超出范围时,为该类实例分配的内存将由公共语言运行时自动回收(垃圾回收)。

结构体实例的值相等性

两个结构体实例的比较是基于值的比较,而类实例的比较则是对其引用的比较。

若要确定两个结构体实例中的实例字段是否具有相同的值,可使用 ValueType.Equals 方法。由于所有结构体都隐式继承于 System.ValueType,因此可以直接在其对象上调用该方法,如以下示例所示:

public struct Person
{public string Name;public int Age;public Person(string name, int age){Name = name;Age = age;}
}static void Main()
{Person p1 = new Person("技术译站", 100);Person p2;p2.Name = "技术译站";p2.Age = 100;if (p2.Equals(p1))Console.WriteLine("p2 和 p1 有相同的值。");Console.ReadKey();
}
// 输出: p2 和 p1 有相同的值。

System.ValueType 的 Equals 是使用反射实现,因为它必须能够确定任何结构体中有哪些字段。在创建自己的结构体时,重写 Equals 方法可以提供特定于你的类型的高效求等算法。

“基于值的相等”这一点和 C# 9.0 中新增的记录(record) 类型具有相似之处,想了解 C# 9.0 可以查看:欢迎来到 C# 9.0。

作者 : Manju lata Yadav 
译者 :技术译民
出品 :技术译站(https://ITTranslator.cn/)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/307782.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

不平凡的2021,末流普本生秋招上岸大厂的历程

&#x1f4fb;叮&#xff01; 2021年接近尾声&#xff0c;周一也开始拾起了年终总结。 回顾2021&#xff0c;有喧嚣&#xff0c;也有欢呼&#xff1b;有奔溃&#xff0c;也有快乐。 但好在✏️ 对待一件又一件的小事上&#xff0c;始终保持着对自己的要求&#x1f4ca; 不…

leetcode491. 递增子序列

一&#xff1a;论语 二:题目 三&#xff1a;上码 class Solution { public:vector<vector<int> >ans;vector<vector<int> >ans1;vector<int> path;void backstacking(vector<int>& nums,int index) {if(path.size() > 2) {ans.pus…

ASP.NET Core 性能优化最佳实践

本文提供了 ASP.NET Core 的性能最佳实践指南。译文原文地址&#xff1a;https://docs.microsoft.com/en-us/aspnet/core/performance/performance-best-practices?viewaspnetcore-3.1积极利用缓存这里有一篇文档在多个部分中讨论了如何积极利用缓存。有关详细信息&#xff0c…

[算法与数据结构] 谈谈线性查找法~

[算法与数据结构] 一文详解线性查找法~&#x1f4c5;前言一、&#x1f4dd;算法基础知识1、什么是算法2、算法的五大特性二、&#x1f4c8;线性查找法1、举例阐述2、实现线性查找法3、使用泛型4、升级改造5、使用自定义类6、循环不变量三、&#x1f4ca;算法复杂度1、简单的复杂…

送福利 | 送书5本《ASP.NET Core项目开发实战入门》带你走进ASP.NET Core开发

《ASP.NET Core项目开发实战入门》从基础到实际项目开发部署带你走进ASP.NET Core开发。ASP.NET Core项目开发实战入门是基于ASP.NET Core 3.1 所写&#xff0c;后续ASP.NET Core 5也会对应更新。简介本书共14章&#xff0c;深入浅出地介绍了ASP.NET Core基础及项目开发方面的知…

海有舟可渡、山有路可循‍‍ —— 大学四年圆满落幕

⛺️前言 仅以此篇文章记录我的大学四年&#xff01; 回忆大学四年&#xff0c;有惊喜、有快乐、有崩溃、有欢呼&#xff1b; 有过无数个为了赶策划、赶ddl的熬夜&#xff0c;更有凌晨2点做志愿活动、凌晨5点赶项目的通宵达旦。 梳理下大学四年的大事件&#xff1a; 大一 …

程序开发天团必备单品,稳定输出还加持千元商务礼限时送!

有这么一个门派他们用强大的思维逻辑频出“大招”用抗造的硬核体能昼夜练习一水儿的格子衫下&#xff0c;个个骨骼精奇深居简出&#xff0c;却默默改变着世界格局他们都使用同一件武器拼的就是个配置高低这与能否称霸武林有着直接关系看看各位高手怎么说“大内”高手 武功唯快不…

了解微前端,深入前端架构的前世今生

前端架构的前世今生&#x1f6f5;前言一、&#x1f6f4;前端架构的前世今生1、架构是如何产生的&#xff1f;2、MVC架构3、前后端分离架构4、Nodejs5、单页面架构&#xff08;1&#xff09;现有单页面架构&#xff08;2&#xff09;单页面架构的优势&#xff08;3&#xff09;单…

leetcode37. 解数独

一:论语 简而言之 就是要一视同仁 对待遇见所有的人要一个态度 二&#xff1a;题目 三:上码 class Solution { public:bool backstacking(vector<vector<char> >& board) {for(int i 0; i < board.size(); i) {for(int j 0; j < board[0].size(); …

跟我一起学.NetCore之.NetCore概述

随着.NetCore版本发布变更&#xff0c;在最近一年左右开始接触到.NetCore&#xff0c;之前只是传闻&#xff0c;并没有动手实操&#xff1b;.NetCore逐渐成熟&#xff0c;大大小小的公司也开始进行使用&#xff0c;感觉再不学习就落后了&#xff0c;于是乎搜索各种资料开始学习…

线程与线程池(一条龙详解)

一:前言 一个问题引出的学习笔记 并发类库提供的线程池实现有哪些? 其实Executors已经为我们封装好了 4 种常见的功能线程池&#xff0c;如下&#xff1a; 定长线程池&#xff08;FixedThreadPool&#xff09;定时线程池&#xff08;ScheduledThreadPool &#xff09;可缓存…

项目升级,无缝对接 .NET 5

开启.NET5时代2020-09-14从NetCore1.1开始学起&#xff0c;然后又从2.0开始讲知识&#xff0c;再到将所有的在线项目升级并长期维护到3.1&#xff0c;转眼已经三年了&#xff0c;一直紧跟着微软的节奏有条不紊的往前走&#xff0c;我相信&#xff0c;只要是从18年末或者19年初跟…

小团队前端部署演化之路

前言 前端部署相对来说其实是一件非常容易的事情&#xff0c;无论是最原始的html页面&#xff0c;还是现在热门的三大框架&#xff0c;最后交付部署的时候&#xff0c;始终会是一些静态文件。虽然简单&#xff0c;但是对于不同的团队来说&#xff0c;都会在不同阶段有最适合他们…

GitHub 全域数字年报:携手推动开源世界的超级协作

2020年1月24日&#xff0c;Wuhan2020开源项目正式发起&#xff0c;在疫情期间累积吸引到了约3000余位技术志愿者以及近1000余位非技术志愿者在线上开展志愿行动与参与。Wuhan2020在成立后的约3个月时间内&#xff0c;通过开源协作的方式在互联网上开展志愿者支持与工作协同&…

leetcode53. 最大子数组和(暴力+贪心)

一:论语 追求利益的同时 我们需要控制度 就好比鹅厂的王者荣耀 赚的盆满钵满 坑坏了多少青少年 但是鹅厂早已经开始控制度了 二:题目 三:上码&#xff08;暴力贪心&#xff09; 1:暴力 class Solution { public:int maxSubArray(vector<int>& nums) {/**暴力解法…

Newbe.Claptrap-一套以“事件溯源”和“Actor模式”作为基本理论的服务端开发框架...

本文是关于 Newbe.Claptrap 项目主体内容的介绍&#xff0c;读者可以通过这篇文章&#xff0c;大体了解项目内容。轮子源于需求随着互联网应用的蓬勃发展&#xff0c;相关的技术理论和实现手段也在被不断创造出来。诸如 “云原生架构”、“微服务架构”、“DevOps” 等一系列关…

NCF框架揭秘直播来了!红包、抽奖、还有神秘嘉宾…(内含彩蛋)

盛派周三技术分享会直播开讲又来啦~为了更好地赋能开发者&#xff0c;盛派已将系统框架 SCF&#xff08;SenparcCoreFramework&#xff09;全部开源&#xff0c;收到了社区非常多的关注&#xff0c;现在 SCF 已正式更名为NCF&#xff08;NeuCharFramework&#xff09;&#xff…

leetcode45. 跳跃游戏 II

一:论语 己所欲 也要勿施于人 &#xff0c;每个人的经历和阅历都是不同的 你凭啥说你认为的很开心的事情 去要求别人呢 二:题目 三:上码 class Solution { public:int jump(vector<int>& nums) {/**思路:1.这里的难点就在于 我们需要判断下一步的的最远跳跃距离…

【翻译】.NET 5 RC1发布

9月14日&#xff0c;.NET5发布了(Release Candidate)RC1版本&#xff0c;RC的意思是指我们可以进行使用&#xff0c;并且RC版本得到了支持&#xff0c;该版本是接近.NET5的版本&#xff0c;也是11月正式版本之前两个RC版本中的其中一个。目前&#xff0c;开发团队正在寻找在.NE…

leetcode1005. K 次取反后最大化的数组和

一:论语 这个用在自己身上感觉值得反省&#xff0c;很多道理我都能明白 也能讲给别人听 但是很多时候 自己往往做的不好 而且还很容易 自我感动 最近真的很讨厌自己这样 不要自我感动 要正向积累 多去做 多去做 这只是个开始 然后慢慢的长进 再者就是坚持 二:题目 三:上码 …