news 2026/4/23 2:08:12

C#.NET struct 全解析:什么时候该用值类型?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C#.NET struct 全解析:什么时候该用值类型?

简介

struct是 值类型(Value Type),用于封装一组相关的数据。
与类(class)相比,结构体通常更轻量,适用于小型、短生命周期的对象。

⚡ 关键特点:

  • 存储在 栈(stack)上(也可能嵌套在堆中,但本质仍是值类型)。

  • 按值传递(赋值/参数传递时会复制整个结构)。

  • 无需垃圾回收(GC),生命周期由作用域决定。

  • 可包含字段、属性、方法、构造函数、运算符重载等。

基本语法

publicstructPoint{publicintX;publicintY;publicPoint(intx,inty){X=x;Y=y;}publicvoidMove(intdx,intdy){X+=dx;Y+=dy;}}

使用:

Pointp1=newPoint(3,4);p1.Move(1,2);Console.WriteLine($"{p1.X},{p1.Y}");// 4, 6

内存模型与分配

分配场景存储位置说明
局部变量最典型场景,生命周期由方法作用域决定
作为类字段包含在类对象内部,但值本身在堆内存中
数组元素数组本身在堆上,每个元素紧密排列

即使struct位于堆中(例如类字段、数组元素),它仍然是值类型,操作时是按值复制。

与 class 的区别

特性class(引用类型)struct(值类型)
内存分配堆(GC 管理)栈/堆中嵌入
传递方式按引用传递(复制引用)按值传递(复制整个对象)
默认构造函数可定义无参/有参系统提供无参构造,用户不能定义
继承支持继承/虚方法不能继承,只能实现接口
空值(null)可以为 null不可为 null(除非Nullable<T>
装箱/拆箱不涉及赋值给object时会装箱
性能分配慢(GC)分配快,生命周期短时更高效

构造函数与初始化

默认构造函数
  • 所有结构体都有一个隐式的无参构造函数,将所有字段初始化为 默认值(如0null)。

  • 用户不能显式定义无参构造函数(C# 10开始支持,但有限制)。

自定义构造函数

可以定义有参构造函数,但必须初始化所有字段。

publicPoint(intx,inty){X=x;// 必须全部赋值Y=y;}
结构体的成员

结构体可以包含:

  • 字段(Field

  • 属性(Property

  • 方法(Method

  • 事件(Event

  • 运算符重载

  • 静态成员

  • 构造函数(但无参构造受限)

不支持:

  • 继承其他类/结构体(只能实现接口)。

  • 明确的析构函数(~Destructor)。

值类型的特性

按值传递

结构体赋值时会复制整个值:

Pointp1=newPoint(1,2);Pointp2=p1;// 复制p2.X=99;Console.WriteLine(p1.X);// 1,不受 p2 修改影响
装箱/拆箱

赋值给object或接口时,会将结构体复制到堆中:

Pointp=newPoint(1,2);objectobj=p;// 装箱:复制到堆Pointp2=(Point)obj;// 拆箱:从堆复制回栈

装箱/拆箱会带来性能开销,应尽量避免频繁发生。

不可变结构体(Immutable struct)

为了避免复制带来的副作用,结构体推荐设计为不可变:

publicreadonlystructPoint{publicintX{get;}publicintY{get;}publicPoint(intx,inty)=>(X,Y)=(x,y);}
实现接口
publicinterfaceIDrawable{voidDraw();}publicstructCircle:IDrawable{publicdoubleRadius{get;}publicPointCenter{get;}publicCircle(doubleradius,Pointcenter){Radius=radius;Center=center;}publicvoidDraw(){Console.WriteLine($"Drawing circle at{Center}with radius{Radius}");}publicdoubleArea=>Math.PI*Radius*Radius;}
structRectangle:IEquatable<Rectangle>{publicintWidth,Height;publicboolEquals(Rectangleother){returnWidth==other.Width&&Height==other.Height;}publicoverrideboolEquals(objectobj)=>objisRectangleother&&Equals(other);publicoverrideintGetHashCode()=>HashCode.Combine(Width,Height);}varr1=newRectangle{Width=10,Height=20};varr2=newRectangle{Width=10,Height=20};Console.WriteLine(r1.Equals(r2));// 输出: True
运算符重载示例
structPoint{publicintX,Y;publicPoint(intx,inty){X=x;Y=y;}publicstaticPointoperator+(Pointa,Pointb){returnnewPoint(a.X+b.X,a.Y+b.Y);}publicoverridestringToString()=>$"({X},{Y})";}varp1=newPoint(1,2);varp2=newPoint(3,4);varsum=p1+p2;Console.WriteLine(sum);// 输出: (4, 6)

结构体的新特性

readonly struct
  • 表示完全不可变。

  • 编译器强制所有字段为readonly

  • 防止无意修改。

publicreadonlystructVector{publicreadonlydoubleX;publicreadonlydoubleY;}
ref struct
  • 只能在栈上分配。

  • 用于高性能场景,如Span<T>

record struct

值类型的 记录类型,支持内建的值比较、with表达式。

publicrecordstructPoint(intX,intY);varp1=newPoint(1,2);varp2=p1with{X=3};// 基于值的复制

高级用法

与模式匹配结合使用
publicstructRGBColor{publicbyteR;publicbyteG;publicbyteB;publicRGBColor(byter,byteg,byteb){R=r;G=g;B=b;}publicvoidDeconstruct(outbyter,outbyteg,outbyteb){r=R;g=G;b=B;}}classProgram{staticstringGetColorName(RGBColorcolor){returncolorswitch{(255,0,0)=>"Red",(0,255,0)=>"Green",(0,0,255)=>"Blue",(255,255,255)=>"White",(0,0,0)=>"Black",_=>"Unknown"};}staticvoidMain(){RGBColorred=newRGBColor(255,0,0);Console.WriteLine(GetColorName(red));// 输出: Red}}

适用场景

✅ 适合:

  • 轻量级、小数据对象(坐标、颜色、矩形、数值容器等)。

  • 高性能计算(避免GC开销)。

  • 频繁创建销毁的对象。

❌ 不适合:

  • 对象非常大(复制开销高)。

  • 需要继承层次。

  • 需要引用语义(共享同一对象)。

如果类型大小超过 16 字节,且频繁传递,建议使用class而不是struct

实战示例

高性能点计算
publicreadonlystructPoint{publicreadonlydoubleX;publicreadonlydoubleY;publicPoint(doublex,doubley)=>(X,Y)=(x,y);publicdoubleDistance(Pointother)=>Math.Sqrt(Math.Pow(X-other.X,2)+Math.Pow(Y-other.Y,2));}voidDemo(){Pointp1=new(1,2);Pointp2=new(4,6);Console.WriteLine(p1.Distance(p2));// 5}
  • GC压力。

  • 值传递保证线程安全。

总结

特性说明
类型值类型(Value Type)
内存分配栈分配或嵌入堆中
继承不能继承其他类/结构体,只能实现接口
构造函数系统提供无参构造;用户可定义有参构造
默认初始化所有字段自动初始化为默认值
传递方式按值传递(复制整个对象)
典型场景小型数据对象(Point、Color)、高性能计算
高级特性readonly structref structrecord struct
设计建议尽量保持不可变,避免装箱,避免过大对象
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 13:12:23

WVP-GB28181-Pro视频点播超时诊断与优化全流程指南

WVP-GB28181-Pro视频点播超时诊断与优化全流程指南 【免费下载链接】wvp-GB28181-pro 项目地址: https://gitcode.com/GitHub_Trending/wv/wvp-GB28181-pro 还在为WVP-GB28181-Pro视频监控平台频繁出现点播超时而头疼吗&#xff1f;作为视频监控系统运维工程师&#xf…

作者头像 李华
网站建设 2026/4/19 9:24:34

[重新设计的文章标题]

[重新设计的文章标题] 【免费下载链接】syncthing-android Wrapper of syncthing for Android. 项目地址: https://gitcode.com/gh_mirrors/sy/syncthing-android [按照新结构组织的文章内容] 【免费下载链接】syncthing-android Wrapper of syncthing for Android. 项…

作者头像 李华
网站建设 2026/4/22 21:15:54

27、多样音频播放器与CD刻录指南

多样音频播放器与CD刻录指南 在音频播放的世界里,有众多出色的工具可供选择,它们能满足不同用户的各种需求。从播放本地音乐到收听网络电台,再到刻录音频CD,每一个环节都有合适的应用程序来实现。 Exaile:GNOME环境下的优秀音频播放器 Exaile是一款类似amaroK的音频播放…

作者头像 李华
网站建设 2026/4/23 13:03:35

Kotaemon支持会话持久化,跨设备记忆用户历史

Kotaemon支持会话持久化&#xff0c;跨设备记忆用户历史 在智能客服系统日益普及的今天&#xff0c;你是否曾有过这样的体验&#xff1a;在手机上刚咨询完订单状态&#xff0c;转到电脑端继续提问时&#xff0c;AI却“失忆”了&#xff0c;要求你从头说起&#xff1f;这种割裂…

作者头像 李华
网站建设 2026/4/23 11:15:20

小红书直播录制终极指南:告别地址失效烦恼

小红书直播录制终极指南&#xff1a;告别地址失效烦恼 【免费下载链接】DouyinLiveRecorder 项目地址: https://gitcode.com/gh_mirrors/do/DouyinLiveRecorder 你是否曾因为小红书直播地址频繁失效而错过精彩内容&#xff1f;每次主播开播都要重新获取链接&#xff0c…

作者头像 李华
网站建设 2026/4/10 20:15:47

代码质量报告自动化生成工具:Sonar CNES Report完全指南

在当今快节奏的软件开发环境中&#xff0c;确保代码质量已成为每个开发团队的核心任务。Sonar CNES Report作为专业的代码质量报告生成工具&#xff0c;能够从SonarQube服务器自动导出详尽的代码分析结果&#xff0c;为技术决策者和开发团队提供数据驱动的质量改进依据。 【免费…

作者头像 李华