news 2026/4/16 14:08:33

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/16 2:54:57

31、守护系统安全:Linux 杀毒与 Ubuntu 使用指南

守护系统安全:Linux 杀毒与 Ubuntu 使用指南 在当今数字化时代,系统安全和软件安装使用是每个用户都关心的问题。本文将为大家详细介绍 Linux 系统下的杀毒软件选择与使用,以及 Ubuntu 桌面版光盘的获取与使用方法,同时还会分享一些实用的在线资源。 1. Linux 杀毒软件 …

作者头像 李华
网站建设 2026/4/16 10:44:11

Web条码技术实战指南:从原理到性能优化的完整解决方案

Web条码技术实战指南&#xff1a;从原理到性能优化的完整解决方案 【免费下载链接】library Multi-format 1D/2D barcode image processing library, usable in JavaScript ecosystem. 项目地址: https://gitcode.com/gh_mirrors/lib/library 在数字化转型浪潮中&#x…

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

CFR Java反编译工具终极指南:5分钟从字节码到可读源码

CFR Java反编译工具终极指南&#xff1a;5分钟从字节码到可读源码 【免费下载链接】cfr This is the public repository for the CFR Java decompiler 项目地址: https://gitcode.com/gh_mirrors/cf/cfr 在现代Java开发中&#xff0c;字节码解析技术已成为开发者必备的核…

作者头像 李华
网站建设 2026/4/16 12:00:21

5分钟学会ProxyPin请求重写:网络调试的完整终极指南

5分钟学会ProxyPin请求重写&#xff1a;网络调试的完整终极指南 【免费下载链接】network_proxy_flutter 开源免费抓包软件ProxyPin&#xff0c;支持全平台系统&#xff0c;用flutter框架开发 项目地址: https://gitcode.com/GitHub_Trending/ne/network_proxy_flutter …

作者头像 李华
网站建设 2026/4/16 11:05:45

超轻量级中文OCR技术完整指南:从零部署到工业级应用

超轻量级中文OCR技术完整指南&#xff1a;从零部署到工业级应用 【免费下载链接】chineseocr_lite 超轻量级中文ocr&#xff0c;支持竖排文字识别, 支持ncnn、mnn、tnn推理 ( dbnet(1.8M) crnn(2.5M) anglenet(378KB)) 总模型仅4.7M 项目地址: https://gitcode.com/gh_mir…

作者头像 李华
网站建设 2026/4/16 11:05:54

终极PPT时间掌控:悬浮计时器让演讲零超时

终极PPT时间掌控&#xff1a;悬浮计时器让演讲零超时 【免费下载链接】ppttimer 一个简易的 PPT 计时器 项目地址: https://gitcode.com/gh_mirrors/pp/ppttimer 还在为演讲时间失控而焦虑吗&#xff1f;每次站在讲台前&#xff0c;是否都在担心内容精彩却败给时间管理&…

作者头像 李华