• C# 结构体介绍



    C# 中的结构体(Struct)是一种值类型数据结构,用于封装不同或相同类型的数据成一个单一的实体。结构体非常适合用来表示轻量级的对象,比如坐标点、颜色值或者复杂的数值类型,因为它们不需要额外的堆分配(与类相比),这可以提高性能。

    下面是使用结构体的一些基本概念:

    定义结构体

    结构体通过 struct 关键字来定义。一个结构体可以包含字段、方法、属性、索引器、运算符、事件和构造函数。
    在VS2022中定义结构体和定义类一样,也是右键添加类,文件产生后把class改为struct即可,例如下面定义了一个Point结构体:

    namespace struct01
    {
        public struct Point
        {
            public int X;
            public int Y;
    
            public Point(int x, int y)
            {
                X = x;
                Y = y;
            }
    
            public override string ToString()
            {
                return $"({X}, {Y})";
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    实例化结构体

    结构体可以通过默认构造函数(无参数的构造函数)或者自定义的构造函数来实例化:

    // 默认构造函数
    Point p1 = new Point();
    
    // 自定义构造函数
    Point p2 = new Point(10, 20);
    
    • 1
    • 2
    • 3
    • 4
    • 5

    结构体的值类型特性

    由于结构体是值类型,当一个结构体实例分配给另一个变量时,其值会被复制。这意味着两个变量将引用两个独立的数据副本。

     Point p3 = new Point(30, 31);
     Point p4 = p3; // p4 是 p3 的副本
     p3.X = 303;     // 结构体是值类型,只修改了 p3 的 X 值,p4 的 X 值不变
    
     Console.WriteLine($"p4.X: {p4.X}");
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在上面代码中,因为结构体是值类型,修改了 p3 的 X 值,p4 的 X 值不变。
    C#中类是引用类型,例如下面的类CPoint:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace struct01
    {
        internal class CPoint
        {
            public int X;
            public int Y;
    
            public CPoint(int x, int y)
            {
                X = x;
                Y = y;
            }
    
            public override string ToString()
            {
                return $"({X}, {Y})";
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    声明类对象

    CPoint cPoint = new CPoint(100, 200);
    CPoint cPoint1 = cPoint;
    
    cPoint1.X = 101;  // 类是引用类型,cPoint1 是 cPoint 的引用,修改 cPoint1 的 X 值,cPoint 的 X 值也会改变
    
    Console.WriteLine($"cPoint.X: {cPoint.X}");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    类是引用类型,cPoint1 是 cPoint 的引用,修改 cPoint1 的 X 值,cPoint 的 X 值也会改变。

    Main函数全部代码如下:

    namespace struct01
    {
        internal class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Struct test");
    
                // 默认构造函数
                Point p1 = new Point();
    
                // 自定义构造函数
                Point p2 = new Point(10, 20);
    
                Point p3 = new Point(30, 31);
                Point p4 = p3; // p4 是 p3 的副本
                p3.X = 303;     // 结构体是值类型,只修改了 p3 的 X 值,p4 的 X 值不变
    
                Console.WriteLine($"p4.X: {p4.X}");
    
                CPoint cPoint = new CPoint(100, 200);
                CPoint cPoint1 = cPoint;
    
                cPoint1.X = 101;  // 类是引用类型,cPoint1 是 cPoint 的引用,修改 cPoint1 的 X 值,cPoint 的 X 值也会改变
    
                Console.WriteLine($"cPoint.X: {cPoint.X}");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    运行结果如下:
    Struct test
    p4.X: 30
    cPoint.X: 101

    结构体和类的区别

    结构体是值类型,而类是引用类型。
    结构体不支持继承,而类支持。
    结构体的实例可以在不使用 new 关键字的情况下创建,这会导致其所有字段被默认初始化,而类的实例必须使用 new。
    结构体通常用于较小的数据结构,类适用于较大的复杂对象。
    结构体的使用场景:

    当你想要封装一小组相关的变量时。
    当你知道数据量不大,且不需要扩展的时候。
    当性能是一个重要因素,且你希望减少GC(垃圾回收)的压力时。

    限制

    结构体不能有默认的(无参)构造函数。
    结构体不能继承其他的结构体或类,并且不能作为基础结构体或类。
    结构体成员不能指定为 abstract, virtual, 或 protected.
    使用结构体的一个关键点就是要理解值类型与引用类型的区别。值类型存储在栈上,而引用类型存储在堆上,这影响了性能和资源的使用。适当地使用结构体可以提高应用程序的性能。

  • 相关阅读:
    elementui中form表单的重置方法resetFields,resetFields不生效
    每日一题31:数据统计之即时配送食物
    25. K 个一组翻转链表
    人工智能的时代---AI的影响
    RabbitMQ 笔记
    使用 Kotlin DSL 编写网络爬虫
    HTML三叉戟,标签、元素、属性各个的意义是什么?
    绘制散点图、曲线图、折线图和环形图失败, 设置迭代次数和进度无法保存图片
    基于JAVA的物流信息管理平台【数据库设计、源码、开题报告】
    网络通信过程的解析
  • 原文地址:https://blog.csdn.net/yao_hou/article/details/134470905