当前位置: 首页 > backend >正文

C# 结构体与类的区别是什么?

结构体是值类型是储存在栈中独立储存的,数据与数据之间不会相互影响,即使将一个结构体赋值给另外一个结构体也不会相互影响。

类是一个模板,实例出来的对象是独立的不会相互影响,但是将一个对象赋值给另一个对象时 会把指向堆内存中数据的指针赋值给另一个对象.从而发生两个变量指向同一个堆内存 一个修改数据 另外一个也修改。

目录

1. 数据类型本质

2. 默认继承行为

3. 实例化方式

4. 默认成员初始化

5. 构造函数特性

6. 内存管理与生命周期

7. 比较行为

8. 适用场景

总结对比表


在 C# 等面向对象编程语言中,结构体(Struct)和类(Class)是两种重要的数据类型,它们在内存管理、行为特性等方面存在显著区别。以下从多个维度详细说明二者的核心差异:

1. 数据类型本质

  • 结构体(Struct):属于值类型(Value Type),直接存储数据本身。
    内存分配在栈(Stack) 上(或作为引用类型的一部分嵌入在堆中),当结构体变量被赋值、传递时,会创建完整的副本
  • 类(Class):属于引用类型(Reference Type),存储的是数据的引用(地址)。
    内存分配在堆(Heap) 上,变量仅保存指向堆中数据的指针,赋值或传递时仅复制引用(不会复制数据本身)。
  • 类实例化出的对象(即类的实例)存储在堆(Heap)中,而指向该对象的引用(变量)则存储在栈(Stack)中。

2. 默认继承行为

  • 结构体:默认继承自 System.ValueType(间接继承自 object),但不能继承其他类或结构体,也不能被其他类继承( sealed 特性)。
    支持实现接口。
  • :默认继承自 object可以继承其他类(单继承),也可以被其他类继承(除非声明为 sealed)。
    同样支持实现接口。

3. 实例化方式

  • 结构体
    • 可以不使用 new 关键字实例化(此时成员变量为默认值,如 int 为 0)。
    • 例如:Point p; p.X = 10;Point 是结构体)。
    • 使用 new 时,会调用构造函数初始化成员。
    • 必须使用 new 关键字调用构造函数实例化(否则变量为 null,直接访问成员会报错)。
    • 例如:Person p = new Person();Person 是类)。

4. 默认成员初始化

  • 结构体
    • 不能在声明时为成员变量设置默认值(需在构造函数中初始化)。
    • 例如:struct Point { public int X = 0; }(编译错误)。
    • 可以在声明时为成员变量设置默认值。
    • 例如:class Person { public int Age = 18; }(合法)。

5. 构造函数特性

  • 结构体
    • 无默认无参构造函数(编译器不会自动生成,若手动定义构造函数,必须为所有成员赋值)。
    • 例如:struct Point { public int X; public Point(int x) { X = x; } }(合法,因初始化了所有成员)。
    • 编译器会自动生成默认无参构造函数(若未手动定义任何构造函数)。
    • 可以定义有参构造函数,且无需显式初始化所有成员(未初始化的成员为默认值)。

6. 内存管理与生命周期

  • 结构体
    • 生命周期与所在作用域一致(如方法内的结构体变量,方法执行结束后栈内存自动释放)。
    • 无需垃圾回收(GC),性能开销较低(适合小型数据结构)。
    • 实例在堆上分配,生命周期由 GC 管理(当没有引用指向时,会被 GC 回收)。
    • 存在 GC 开销,适合大型、复杂的对象(如业务实体)。

7. 比较行为

  • 结构体
    • 默认按值比较(比较所有成员是否相等)。
    • 例如:两个 Point 结构体,若 X 和 Y 分别相等,则认为相等。
    • 默认按引用比较(比较是否指向堆中同一个实例)。
    • 例如:两个 Person 类实例,即使成员完全相同,若引用不同则认为不相等(需重写 Equals 方法实现值比较)。

8. 适用场景

  • 结构体
    • 适合表示小型、简单的数据(如坐标 Point、颜色 Color、日期 DateTime 等)。
    • 强调数据的值语义(传递时需要副本),且无需继承或多态特性。
    • 适合表示复杂的对象(如 UserOrder 等业务实体)。
    • 需要继承、多态,或实例较大、需要长期存在(通过引用共享)的场景。

总结对比表

特性结构体(Struct)类(Class)
数据类型值类型引用类型
内存分配栈(或嵌入堆)
赋值 / 传递行为复制值(副本)复制引用(共享实例)
继承不能继承 / 被继承(除接口)支持继承和被继承
实例化可省略 new必须用 new
成员默认值不允许声明时初始化允许声明时初始化
构造函数无默认无参构造函数,需初始化所有成员有默认无参构造函数,可部分初始化
比较方式默认值比较默认引用比较
适用场景小型简单数据,值语义复杂对象,引用语义,需继承多态

通过以上区别可以看出,结构体和类的选择主要取决于数据的复杂度、是否需要共享引用以及是否依赖继承多态等特性。

C# 结构体https://blog.csdn.net/LZQqqqqo/article/details/149511030?spm=1001.2014.3001.5502C# 面向对象__类_对象https://blog.csdn.net/LZQqqqqo/article/details/149546454?spm=1001.2014.3001.5502

http://www.xdnf.cn/news/17781.html

相关文章:

  • 【论文阅读 | CVPR 2024 | UniRGB-IR:通过适配器调优实现可见光-红外语义任务的统一框架】
  • C++ 23种设计模式的分类总结
  • 软件著作权产生与登记关键点
  • PiscTrace基于YOLO追踪算法的物体速度检测系统详解
  • openvsx搭建私有插件仓库
  • mysql查询中的filesort是指什么
  • 云蝠智能 VoiceAgent:重构物流售后场景的智能化引擎
  • 构建Node.js单可执行应用(SEA)的方法
  • 飞算JavaAI合并项目实战:7天完成3年遗留系统重构
  • BitDock——让你的Windows桌面变为Mac
  • 网络层协议——IP
  • 前端Vite介绍(现代化前端构建工具,由尤雨溪开发,旨在显著提升开发体验和构建效率)ES模块(ESM)、与传统Webpack对比、Rollup打包
  • 设计模式(1)
  • vue2和vue3的区别
  • httpx 设置速率控制 limit 时需要注意 timeout 包含 pool 中等待时间
  • 【2025年 Arxiv 即插即用】 特征融合新突破:空间–光谱注意力融合模块 SAFFM 强势登场!
  • Vite 为什么比 Webpack 快?原理深度分析
  • 【Linux系统】进程的生命旅程:从创建到独立的演绎
  • RTC时钟倒计时数码管同步显示实现(STC8)
  • 如何安装 scikit-learn Python 库
  • 8. 函数简介
  • 鸿蒙NEXT如何通过userAgent区分手机端和pc端
  • 全栈:SSM项目的分支结构以及对应的每个的文件的作用
  • 古中医学习笔记专题文章导航
  • Stability AI技术浅析(一)
  • 力扣top100(day03-02)--图论
  • 【Java虚拟机】JVM相关面试题
  • RabbitMQ高级特性——消息确认、持久性、发送方确认、重试
  • tlias智能学习辅助系统--Maven 高级-私服介绍与资源上传下载
  • 反射在Spring IOC容器中的应用——动态创建Bean (补充)