C# 结构体 和 类 的区别

结构体(struct)是值类型(Value Type)

和类(class)不同,结构体在赋值和传参时是复制值本身,而不是引用地址。


✅ 一、结构体的基本使用示例:

using System;struct Point
{public int X;public int Y;public Point(int x, int y)  // 构造函数{X = x;Y = y;}public void Print(){Console.WriteLine($"X = {X}, Y = {Y}");}
}class Program
{static void Main(){Point p1 = new Point(3, 4);Point p2 = p1;  // 值复制p2.X = 100;p1.Print();  // 输出: X = 3, Y = 4p2.Print();  // 输出: X = 100, Y = 4}
}

🔍 说明

  • p2 = p1值复制,修改 p2.X 不影响 p1.X

  • 如果是类,就会出现两个变量共享一份数据的情况。


✅ 二、结构体和类的区别(简要对比):

特性结构体(struct)类(class)
类型值类型引用类型
存储堆栈上堆上
继承不支持继承支持继承
默认构造函数不可自定义无参构造函数可以定义任意构造函数
分配性能更快相对较慢(需要GC)


✅ 三、结构体使用场景

结构体适合表示小型的、行为简单的数据对象,比如:

  • 坐标(Point)

  • 颜色(Color)

  • 时间(DateTime)

  • 金额(Money)


✅ 四、使用场景扩展:结构体作为方法参数

struct Size
{public int Width;public int Height;public Size(int w, int h){Width = w;Height = h;}
}class Program
{static void ModifySize(Size s){s.Width = 999;}static void Main(){Size mySize = new Size(100, 200);ModifySize(mySize);Console.WriteLine(mySize.Width);  // 结果仍是 100,未被修改}
}

🔍 原因:传值类型是拷贝副本,函数内修改不会影响原始变量。


✅ 五、ref 修饰结构体参数(传引用)

static void ModifySize(ref Size s)
{s.Width = 999;
}static void Main()
{Size mySize = new Size(100, 200);ModifySize(ref mySize);Console.WriteLine(mySize.Width);  // 现在是 999,修改生效
}

补充:

Q:结构体既然不可自定义无参构造函数,那么它的无参构造函数是真实存在的吗?

A:

结论先行:

在 C# 中,结构体确实有一个无参构造函数但它是编译器自动生成的,不允许你自定义或重写(在 .NET Framework 和 .NET Core/.NET 5 之前如此;.NET 6 起有例外,见后面)。 


✅ 一、为什么结构体有无参构造函数?

结构体是值类型,值类型在声明后必须被赋予一个确定的值,所以:

  • C# 编译器会默认生成一个“全字段为默认值”的无参构造函数

  • 你不能自己定义一个无参构造函数(除非是 .NET 6+ 且加 public)。


✅ 二、演示:结构体的默认构造行为

struct MyStruct
{public int X;public int Y;
}class Program
{static void Main(){MyStruct s = new MyStruct();  // 编译通过!Console.WriteLine($"{s.X}, {s.Y}");  // 输出: 0, 0}
}

即使你没定义构造函数,new MyStruct() 会把所有字段初始化为默认值(int → 0)。


✅ 三、不能自定义无参构造函数(.NET 6 前)

下面这个写法在 .NET 5 或更早版本中会报错

struct MyStruct
{public int X;// ❌ 编译错误:结构体不能包含无参数的构造函数public MyStruct()  {X = 1;}
}

错误信息(翻译):

错误 CS0568:结构体不能定义显式的无参数构造函数

真实报错如图 VS2022 .NET5

同样的代码改成 .NET8 框架就没事了,允许定义无参构造函数,如图。


✅ 四、.NET 6 起的新特性(允许定义无参构造函数)

.NET 6 / C# 10 起,你可以写:

struct MyStruct
{public int X;// ✅ .NET 6+ 支持!public MyStruct(){X = 42;}
}

但要注意:

  • new MyStruct() 现在会调用你自定义的构造函数,而不是“全 0 初始化”。

  • 只有在启用了 .NET 6+ 项目环境和编译器才能生效。


✅ 五、如果结构体不使用 new 会怎样?

MyStruct s;
s.X = 10; // ✅ 合法
Console.WriteLine(s.X); // 10

注意:

  • 不用 new 就要 手动初始化所有字段,否则不能访问它。

✅ 总结一下:

特性说明
是否有无参构造函数有,编译器默认生成,字段为默认值(int 为 0)
能否自定义无参构造函数❌ 在 .NET 6 前不可以;✅ .NET 6 起可以
默认构造函数会干嘛初始化所有字段为类型默认值
new struct() vs 不用 newnew:所有字段变为默认值;不用 new:必须手动赋值所有字段

 


补充2:

Q:既然结构体不能被继承,那结构体能继承类或者接口吗?

结论:

能否继承答案
结构体能继承类吗❌ 不能
结构体能被继承吗❌ 不能(sealed)
结构体能继承接口吗✅ 可以

✅ 一、结构体不能继承类,也不能被继承

struct MyStruct : MyBaseClass  // ❌ 错误:结构体不能继承类
{
}

会报错:

错误 CS0527: 'MyStruct': 结构体不能从类 'MyBaseClass' 继承

因为:

  • 结构体是值类型,不支持类的继承链结构

  • 结构体在 CLR(公共语言运行库)中是 sealed 的


✅ 二、结构体可以实现接口 ✅

interface IPrintable
{void Print();
}struct MyStruct : IPrintable
{public int Value;public void Print(){Console.WriteLine($"Value = {Value}");}
}class Program
{static void Main(){MyStruct s = new MyStruct { Value = 123 };s.Print();  // 输出:Value = 123// 也可以通过接口调用IPrintable printable = s;printable.Print();  // 仍然输出:Value = 123}
}

 ✅ 三、结构体实现接口的注意事项(值类型封装拆箱问题)

结构体是值类型,如果你将它转换成接口类型,会发生装箱(Boxing),性能上会有一些开销:

IPrintable printable = s; // ⚠️ 会进行装箱,把值类型放到堆上

✅ 四、总结对比:

特性类(class)结构体(struct)
是否值类型否(引用类型)✅ 是
是否能继承类✅ 可以❌ 不可以
是否能实现接口✅ 可以✅ 可以
是否能被继承✅ 可以❌ 不可以(sealed)
是否支持虚方法✅ 可以❌ 不能虚方法/override(除非显示接口实现)

Q:sealed 是什么 

英/siːld/
adj.密封的;未知的

A:sealed 是 C# 中用于控制 继承 的关键字,主要用于防止类被继承。


✅ 一、sealed 是什么?

sealed 修饰符表示这个类(或方法)不能被继承或重写


✅ 二、语法示例:

🔹1. 阻止类被继承

sealed class Animal
{public void Speak() => Console.WriteLine("Animal sound");
}// ❌ 错误:不能从密封类继承
class Dog : Animal { } // 编译错误

📌 报错信息:

错误 CS0509:无法从密封类型 'Animal' 派生

报错如图: 


🔹2. 阻止方法被重写(配合 override

你也可以用 sealed 修饰继承链中的方法,阻止再被 override:

class Animal
{public virtual void Speak() => Console.WriteLine("Animal");
}class Dog : Animal
{public sealed override void Speak() => Console.WriteLine("Dog");
}class Husky : Dog
{// ❌ 错误:Speak 已 sealed,不能重写// public override void Speak() => Console.WriteLine("Husky");
}

 ✅ 三、结构体默认是 sealed 吗?

是的!

struct MyStruct { }
  • 结构体(struct)默认就是 sealed,不能继承

  • 所以你 不能在 struct 上显示写 sealed,否则会报错。


 ✅ 四、sealed 的实际应用场景

应用场景说明
安全性防止别人继承你写的类(尤其是框架库)
性能优化JIT 编译器可以优化 sealed 方法的调用路径(非虚调用)
明确设计意图告诉使用者这个类不能被扩展或重写

✅ 五、sealed 与 abstract 是对立的吗?

是的,sealed 表示“不能被继承”,而 abstract 表示“必须被继承”。

修饰符含义
sealed不能被继承
abstract必须被继承
sealed abstract❌ 不能一起用,语义冲突

 

✅ 总结一句话:

sealed 是用于禁止继承或重写的关键字,常用于类或方法上。结构体本身默认就是 sealed 的,不能被继承。

 

 

仅供学习参考,如有侵权联系我删除。

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

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

相关文章

MacBook Air M4 安装 VMware Fusion Pro

VMware Fusion Pro已经对消费者免费了,在Windows系统上的安装和使用教程比较多,Mac上竟然没多少,还充斥着大量的广告以及付费软件,所以趁着今天要安装虚拟机,记录一下完整过程。 1,注册博通账号与登录 首…

vue的优缺点

Vue的优点轻量级框架 Vue的核心库仅关注视图层,体积小巧(约20KB),加载速度快,适合快速开发小型到中型项目。易于上手 文档清晰且中文友好,API设计简洁,学习曲线平缓。熟悉HTML、CSS和JavaScript…

闲庭信步使用图像验证平台加速FPGA的开发:第七课——获取RAW图像

(本系列只需要modelsim即可完成数字图像的处理,每个工程都搭建了全自动化的仿真环境,只需要双击top_tb.bat文件就可以完成整个的仿真,大大降低了初学者的门槛!!!!如需要该系列的工程…

在前端项目中是如何解决跨域的

📘 前端项目中跨域问题及解决方式详解(Vite 项目)一、🌐 什么是跨域?跨域(Cross-Origin) 指的是在浏览器中,前端页面与服务器之间的协议、域名或端口不一致而引发的安全限制。✅ 浏览…

代码审计-Struts2漏洞分析

一、Struts2介绍 Struts2 是一个基于 MVC(Model-View-Controller) 设计模式的开源 Java Web 应用框架,由 Apache 软件基金会维护。它是 Struts1 和 WebWork 框架的整合产物,以 WebWork 为核心,通过拦截器机制实现业务逻…

三、神经网络——网络优化方法

三、网络优化方法 1.梯度下降算法梯段下降算法是一种寻找使损失函数最小化的方法,从数学上的角度来看,梯度的方向是函数增长速度最快的方向,那么梯度的反方向就是函数减少最快的方向,所以有WijnewWijold−η∂E∂WijW_{ij}^{new} …

HTML/JOSN复习总结

HTML 基础 什么是 HTML? 1.HTML是一门语言,所有的网页都是用HTML这门语言编写出来的 2.HTML(HyperText Markup Language):超文本标记语言。 >超文本:超越了文本的限制,比普通文本更强大。除了文字信息,还可以定义图片、音频、视频等内…

Golang中的内置类型

A. int B. string C. struct D. array 首先,内置类型是指不需要引入任何关于这些数据类型的包,就可以引用的数据类型。那么,内置类型主要包括基本类型,复合类型,控制并发,高级抽象,特殊类型。…

通过命名空间引用了 Application 类,php不会自动包含路径文件吗?

示例代码:报错提示找不到Application类 use mvc\core\Application;$app new Application(); // 定义路由 $app->get(/, HomeControllerindex); $app->get(/user, UserControllershow); $app->post(/user, UserControllercreate);// 运行应用 $app->run…

PlantUML 基础使用技术文档

目录 摘要 1. 什么是 PlantUML 2. 安装与环境配置 2.1 本地使用 2.2 在线使用 3. 基本语法 3.1 示例:系统架构图 3.2 常用元素 4. 渲染方式 4.1 VSCode 4.2 在线渲染 4.3 生成图片 5. 推荐实践 6. 常见图类型 7. 进阶功能 8. 典型应用场景 摘要 Pl…

Android Notification 通过增加addAction 跳转回Service重新执行逻辑

1.场景描述在App内升级过程中,apk下载过程中网络波动导致连接超时,下载失败后Service生命周期结束。前台通知也被清除。2.解决思路在通知栏中增加重试按钮重启下载服务。3.代码NotificationManager mNotificationManager (NotificationManager) getSy…

带货视频评论的用户洞察 科大讯飞AI算法赛 Datawhale AI夏令营

赛题 2025 iFLYTEK AI开发者大赛https://challenge.xfyun.cn/topic/info?typevideo-comment-insight 一、赛事背景 在电商直播爆发式增长的数字化浪潮下,短视频平台积累了海量带货视频及用户互动数据。这些数据不仅是消费者对商品体验的直接反馈,更蕴…

JAVA生成PDF(itextpdf)

java生成PDF有多种方式&#xff0c;比如itextpdf、 Apache PDFBox、Flying Saucer (XHTMLRenderer)、 OpenPDF等。今天要介绍的是itextpdf&#xff0c;及在开发过程中处理的问题。1. 引入POM<!--PDF导出POM--><dependency><groupId>com.itextpdf</groupId…

[爬虫知识] 深入理解多进程/多线程/协程的异步逻辑

相关爬虫实战案例&#xff1a;[爬虫实战] 多进程/多线程/协程-异步爬取豆瓣Top250 相关爬虫专栏&#xff1a;JS逆向爬虫实战 爬虫知识点合集 爬虫实战案例 逆向知识点合集 前言&#xff1a; 面对海量的目标数据&#xff0c;传统单线程、同步的爬取方式往往效率低下&#x…

Oracle RAC 11.2.0.4 更新SYSASM和SYS密码

前言 从技术角度看&#xff0c;SYSASM是Oracle 10g R2引入的ASM管理员角色&#xff0c;而SYS是数据库实例的超级用户&#xff0c;SYS账户无法管理ASM磁盘组。SYSASM权限是集群级别的&#xff0c;比如在添加磁盘组时&#xff0c;这个操作会影响所有节点&#xff1b;而SYS用户的权…

Vue》》总结

官网 vue路由的query参数、mixin 混入 vue cli 脚手架之配置代理 VUE SAP、 MPA&#xff0c;&#xff0c;组件开发、VDOM、双向数据绑定 Vue Props 、Mixin 、路由守卫 vue router query参数 Vue props以及其他通信方式, vue响应式 原理 追加响应式数据&#xff0c;数组响应式 …

Nginx 中的负载均衡策略

Nginx 是一个高性能的 HTTP 和反向代理服务器&#xff0c;广泛用于负载均衡场景。它支持多种负载均衡策略&#xff0c;可以帮助你优化资源利用、提高响应速度和增加系统的可用性。以下是 Nginx 中几种常见的负载均衡策略及其配置方法&#xff1a; 1. 轮询&#xff08;Round Rob…

用 Python 将分组文本转为 Excel:以四级词汇为例的实战解析

一、背景引入&#xff1a;从“人工整理”到“自动化处理”的转变 在英语学习过程中&#xff0c;我们经常会接触各种分组整理的词汇表&#xff0c;比如“Group1”对应一组单词及释义&#xff0c;随后是“Group2”、“Group3”等等。如果你下载了一个 .txt 格式的四级词汇表&…

Ffmpeg滤镜

打开设备 添加滤镜 循环录制文件 #include "libavdevice/avdevice.h" #include "libavformat/avformat.h" #include "libavcodec/avcodec.h" #include "libavfilter/avfilter.h" #include "libavfilter/buffersink.h" #incl…

HarmonyOS AI辅助编程工具(CodeGenie)UI生成

UI Generator基于BitFun Platform AI能力平台&#xff0c;用于快速生成可编译、可运行的HarmonyOS UI工程&#xff0c;支持基于已有UI布局文件&#xff08;XML&#xff09;&#xff0c;快速生成对应的HarmonyOS UI代码&#xff0c;其中包含HarmonyOS基础工程、页面布局、组件及…