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

C#中结构(Struct)

一、什么是结构(Struct)?

结构(struct)是 C# 中一种值类型数据结构,用于封装小型相关数据。它与类(class)类似,可包含字段、属性、方法等成员,但本质是值类型(存储在栈上),而类是引用类型(存储在堆上)。

核心特点

  • 值类型,赋值时直接复制数据(而非引用);
  • 适合存储小型、简单的数据(如坐标、颜色、日期等);
  • 不能被继承(密封类型),但可实现接口。
二、结构的定义语法
// 基本语法
访问修饰符 struct 结构名 : 接口1, 接口2...
{// 成员(字段、属性、方法、构造函数等)
}

示例:定义一个表示二维坐标的结构

public struct Point
{// 字段(通常私有,通过属性暴露)private int _x;private int _y;// 构造函数(必须初始化所有字段)public Point(int x, int y){_x = x;_y = y;}// 属性(封装字段,提供访问控制)public int X { get => _x; set => _x = value; }public int Y { get => _y; set => _y = value; }// 方法(定义行为)public void Move(int deltaX, int deltaY){_x += deltaX;_y += deltaY;}// 重写ToString()方法public override string ToString(){return $"({X}, {Y})";}
}
三、结构的核心特性
1. 是值类型,存储在栈上
  • 结构的实例直接存储数据(而非引用),赋值时会复制完整数据。

示例:

Point p1 = new Point(1, 2);
Point p2 = p1; // 复制p1的所有数据到p2(值类型特性)
p2.X = 100;    // 修改p2不会影响p1Console.WriteLine(p1); // 输出:(1, 2)
Console.WriteLine(p2); // 输出:(100, 2)
2. 不能有无参数构造函数
  • 结构默认有一个隐式的无参数构造函数(由编译器自动生成),会将所有字段初始化为默认值(如 int 为 0,bool 为 false)。

  • 开发者不能自定义无参数构造函数(编译报错),但可定义带参数的构造函数,且必须在其中初始化所有字段

    // 错误示例:不能自定义无参数构造函数
    public struct BadStruct
    {public BadStruct() { } // 编译报错:结构不能包含显式的无参数构造函数
    }// 正确示例:带参数构造函数必须初始化所有字段
    public struct GoodStruct
    {private int _a;private string _b;public GoodStruct(int a, string b){_a = a;_b = b; // 必须初始化所有字段,否则编译报错}
    }
    3. 不能被继承(密封类型)
  • 结构是 sealed(密封)的,无法作为基类被其他结构或类继承,但可以实现接口
    // 定义接口
    public interface IMovable
    {void Move(int x, int y);
    }// 结构实现接口
    public struct Point : IMovable
    {private int _x;private int _y;public Point(int x, int y){_x = x;_y = y;}// 实现接口方法public void Move(int deltaX, int deltaY){_x += deltaX;_y += deltaY;}
    }
    4. 可以包含的成员

结构可包含与类类似的成员,但有一些限制:

  • 允许:字段、属性、方法、构造函数(带参数)、索引器、事件、嵌套类型等。
  • 不允许:无参数构造函数、析构函数(~StructName())、protected 修饰符(因不能继承)。
5. 初始化方式

结构的实例化有两种方式:

  • 使用 new 关键字:调用构造函数,初始化所有字段。

  • 直接赋值:不使用 new,但必须先为所有字段赋值才能使用(否则编译报错)。

    // 方式1:使用new调用构造函数
    Point p1 = new Point(1, 2);// 方式2:直接赋值(必须初始化所有字段)
    Point p2;
    p2.X = 3; // 错误:未初始化所有字段,不能使用
    p2.Y = 4; // 正确:先赋值所有字段,再使用  而不是赋值属性
    Point p3;
    p3.x = 3;
    p3.y = 4;
    Console.WriteLine(p3); // 输出:(3, 4)
    四、结构与类的核心区别
    对比项结构(struct)类(class)
    类型值类型(存储在栈上)引用类型(存储在堆上)
    赋值行为复制所有数据(值传递)复制引用地址(引用传递)
    继承不能被继承,可实现接口可继承,可实现接口
    构造函数不能自定义无参数构造函数可自定义无参数构造函数
    默认初始化隐式无参构造函数初始化所有字段为默认值无参构造函数需手动定义(否则默认 null)
    析构函数不允许定义允许定义(用于释放非托管资源)
    适用场景小型数据(如坐标、颜色、数值对)复杂对象(如 Person、Order)
    五、结构的使用场景

结构适合存储小型、简单、数据优先的实体,典型场景:

  1. 存储坐标或位置:如 Point(x,y)、Rectangle(宽、高、左上角坐标)。
  2. 表示数值类型组合:如 Currency(金额、货币单位)、DateTime(年、月、日)。
  3. 轻量级数据传输:如方法返回多个值时,用结构封装比用类更高效。

示例:系统内置结构

C# 中很多基础类型都是结构,例如:

  • intSystem.Int32)、doubleSystem.Double
  • DateTimeTimeSpan
  • PointRectangle(System.Drawing 命名空间)
六、结构的性能考量
  • 优势:作为值类型,结构在栈上分配和释放速度快,适合频繁创建和销毁的小型数据。
  • 注意点
  • 避免定义大型结构(如包含多个字段或大数组),否则复制时会占用大量栈内存,导致性能下降(此时应改用类)。

  • 结构作为方法参数传递时,默认是值传递(复制完整数据),若结构较大,建议用 ref 或 in 关键字传递引用,减少复制开销:

    // 用ref传递结构引用(避免复制)
    void ModifyPoint(ref Point p)
    {p.X = 100;
    }Point p = new Point(1, 2);
    ModifyPoint(ref p); // 直接修改原结构,不复制
    Console.WriteLine(p); // 输出:(100, 2)
    七、常见问题解答
  • Q:结构可以为 null 吗?
  • A:默认不能。但可通过可空值类型Nullable<StructName> 或 StructName?)让结构为 null:
    Point? p = null; // 可空结构,p.HasValue 为 false
    p = new Point(1, 2); // 赋值后 p.HasValue 为 true

 Q:结构的字段可以初始化默认值吗?

A:在 C# 10 及以上版本中,允许直接为结构的字段设置默认值:

public struct Point
{private int _x = 0; // 允许(C# 10+)private int _y = 0;
}

Q:结构和类如何选择?

A:遵循 “大小原则”:

  • 数据量小(字段少且类型简单)→ 用结构;
  • 数据量大或需要继承、复杂行为 → 用类。
八、完整案例:结构的综合使用
using System;// 定义表示颜色的结构(ARGB值)
public struct Color : IEquatable<Color>
{// 字段(带默认值,C# 10+支持)private byte _alpha = 255;private byte _red;private byte _green;private byte _blue;// 构造函数(初始化所有字段)public Color(byte red, byte green, byte blue){_red = red;_green = green;_blue = blue;// _alpha 有默认值,无需显式初始化}public Color(byte alpha, byte red, byte green, byte blue){_alpha = alpha;_red = red;_green = green;_blue = blue;}// 属性public byte Alpha => _alpha;public byte Red => _red;public byte Green => _green;public byte Blue => _blue;// 方法:判断是否与另一个Color相等public bool Equals(Color other){return _alpha == other._alpha &&_red == other._red &&_green == other._green &&_blue == other._blue;}// 重写ToString()public override string ToString(){return $"ARGB({_alpha}, {_red}, {_green}, {_blue})";}
}class Program
{static void Main(){// 创建结构实例Color red = new Color(255, 0, 0);Color transparentRed = new Color(128, 255, 0, 0);// 赋值(值复制)Color redCopy = red;Console.WriteLine(redCopy); // 输出:ARGB(255, 255, 0, 0)// 比较相等性Console.WriteLine(red.Equals(transparentRed)); // 输出:False// 可空结构Color? nullColor = null;Console.WriteLine(nullColor.HasValue); // 输出:False}
}

总结

结构是 C# 中高效的值类型数据容器,适合存储小型、简单的数据。其核心特性包括:值类型存储、不能继承、无自定义无参构造函数等。使用时需根据数据大小和复杂度,在结构与类之间合理选择,以优化程序性能。

http://www.dtcms.com/a/474062.html

相关文章:

  • 长春市网站建设深圳建设工程交易服务网老网站
  • 做视频网站用什么云盘好手机网站打开很慢
  • 沈阳市网站建设企业网站费用估算
  • 构建AI智能体:六十一、信息论完全指南:从基础概念到在大模型中的实际应用
  • SLAM | 视觉SLAM中的退化问题:定义、成因、表现与解决方案
  • 【YOLO 模型进阶】(2)YOLO v1 超详解:从网络架构到优缺点剖析
  • 临近做网站wordpress邮件美化
  • 海外营销网站建设wordpress 站内通知
  • ESP32 VSCode开发环境配置
  • 全栈监控系统搭建:Prometheus+Grafana前后端埋点方案
  • PDF Arranger下载和安装教程(附安装包)
  • 做图片带字的网站专业烟台房产网站建设
  • SoftMotion: DriveInterface: Analog
  • 公司网站公司简介宣传夸大受处罚电子产品网页设计
  • asp网站怎么下载源码大品牌网站建设
  • for循环套for循环(Java基础语法)
  • 运维的概念以及流程零基础入门到精通
  • 网站建设最难的是什么美食网站开发前期准备
  • cpp http 客户端与服务端 POST请求
  • 门户网站开发淘客网站备案教程
  • 【PHP】利用 xlswriter 扩展导出的Excel文件报错问题
  • wordpress+制作首页模板下载网站优化公司推荐
  • SDKMAN工具来实现JDK版本的管理
  • Einops vs PyTorch 张量操作对比指南
  • 钉钉提醒业务系统源码,网站定时钉钉提醒业务系统
  • CentOS 7 安装 bzip2-libs-1.0.6-13.el7.x86_64.rpm 的详细步骤
  • 太原手手工网站建设公司贵阳市建设管理信息网站
  • 树和二叉树——一文速通
  • 轻松可视化数据的利器——JSON Crack
  • 美橙互联网站后台推广计划和推广单元有什么区别