C#中struct, class的使用区别

 更新时间:2026年01月09日 10:09:57   作者:_DRAGON__XU  
类和结构体是C#中用于定义数据类型的关键字,它们在内存分配、生命周期管理、性能等方面存在显著差异,下面就来详细的介绍一下这两者的区别,感兴趣的可以了解一下

在 C# 中,classstruct 都用于定义数据类型,但它们在多个方面存在显著的差异。主要的区别体现在内存分配、生命周期、性能等方面。下面是它们的主要区别:

1.内存分配

  • class(类):类是引用类型。当创建一个类的实例时,内存分配在 堆 上(Heap)。在堆上分配的对象通常会由垃圾回收器(GC)自动管理生命周期。
  • struct(结构体):结构体是值类型。当创建一个结构体的实例时,内存分配在 栈 上(Stack)。值类型的对象直接存储其值,而不是引用其他数据。

2.类型存储方式

  • class:类对象存储的是对实际数据的引用(地址),即 引用类型。这意味着当多个变量引用同一个对象时,它们都指向同一块内存区域。
  • struct:结构体存储的是实际的数据值,即 值类型。当结构体被赋值给另一个变量时,会复制整个结构体的内容,而不是引用原始结构体。

3.默认构造函数

  • class:类可以有自定义构造函数,并且支持默认构造函数(如果没有显式定义构造函数,编译器会自动生成一个无参的构造函数)。
  • struct:结构体也可以有自定义构造函数,但编译器会自动提供一个 无参数的默认构造函数,不能被重写。结构体的构造函数必须初始化所有字段。

4.垃圾回收与生命周期

  • class:类对象的生命周期由垃圾回收器管理。当一个类实例没有任何引用指向它时,GC 会自动回收它。
  • struct:结构体的生命周期通常由栈管理,超出作用域时自动销毁。由于结构体通常不在堆上分配内存,因此不需要垃圾回收器来管理其生命周期。

5.继承

  • class:类支持继承,一个类可以继承自另一个类。类可以是基类,也可以是派生类。
  • struct:结构体 不支持继承。结构体不能继承自其他结构体或类,但它们可以实现接口。

6.默认值

  • class:类的实例默认初始化为 null,表示没有引用指向任何对象。
  • struct:结构体默认初始化为该结构体类型的零值,所有字段的值都为默认值(例如,数值类型的字段为 0,布尔类型为 false)。

7.适用场景

  • class:适用于需要共享数据、需要继承或需要复杂行为的场景。类可以包含复杂的状态和方法,通常用于管理资源(如数据库连接、文件操作等)。
  • struct:适用于轻量级的数据结构,通常包含少量数据,且需要快速复制的场景。结构体一般用于表示较小的对象,如点、矩形、颜色等,不应包含过多的方法或复杂的行为。

8.传值与传引用

  • class:类对象在传递给方法时,传递的是对象的引用,也就是说,方法内部对对象的修改会影响原始对象。
  • struct:结构体在传递给方法时,传递的是值的副本,即方法内部对结构体的修改不会影响原始结构体。

9.内存分配效率

  • class:类对象的内存分配较慢,因为它们是在堆上分配内存,并且需要由垃圾回收器管理生命周期。
  • struct:结构体的内存分配较快,因为它们通常在栈上分配,且没有垃圾回收的开销。但如果结构体过大(包含很多字段),在栈上传递时可能会带来性能问题。

10.示例代码

class示例:

class Person
{
    public string Name;
    public int Age;

    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

class Program
{
    static void Main()
    {
        Person p1 = new Person("Alice", 30);
        Person p2 = p1;  // p2 引用同一个对象

        p2.Name = "Bob";
        Console.WriteLine(p1.Name);  // 输出 "Bob"
    }
}

在这个例子中,p1p2 引用了同一个 Person 对象。修改 p2 中的 Name 属性也会影响 p1,因为它们指向同一块内存。

struct示例:

struct Point
{
    public int X;
    public int Y;

    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }
}

class Program
{
    static void Main()
    {
        Point p1 = new Point(10, 20);
        Point p2 = p1;  // p2 是 p1 的副本

        p2.X = 30;
        Console.WriteLine(p1.X);  // 输出 10
    }
}

在这个例子中,p2p1 的副本,修改 p2 不会影响 p1,因为它们是值类型,赋值时会创建副本。

总结:

特性class (引用类型)struct (值类型)
内存分配
生命周期管理垃圾回收器管理自动销毁(超出作用域时销毁)
是否支持继承支持继承不支持继承
默认值null所有字段初始化为零值
是否实现接口可以实现多个接口可以实现多个接口
赋值与传递传递引用(引用类型)传递值(复制数据)
适用场景适用于较复杂的对象,涉及共享数据和继承的场景适用于小型数据结构,要求高效的复制与传递的场景
内存效率内存分配较慢,需要垃圾回收内存分配较快,不涉及垃圾回收

在选择使用 class 还是 struct 时,主要依据数据的大小、结构的复杂度、性能需求以及是否需要继承等因素。一般来说,如果对象的大小较大或需要复杂的行为,使用 class;如果是简单的数据结构并且需要高效的复制操作,可以使用 struct

到此这篇关于C#中struct, class的使用区别的文章就介绍到这了,更多相关C# struct, class区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C#/VB.NET读取条码类型及条码在图片中的坐标位置实例

    C#/VB.NET读取条码类型及条码在图片中的坐标位置实例

    我们在创建条形码时,如果以图片的方式将创建好的条码保存到指定文件夹路径,可以在程序中直接加载图片使用;已生成的条码图片,需要通过读取图片中的条码信息,如条码类型、条码绘制区域在图片中的四个顶点坐标位置等,可参考本文中的方法
    2023-10-10
  • WebService 的简单封装接口调用方法

    WebService 的简单封装接口调用方法

    这篇文章主要介绍了WebService 的简单封装接口调用方法,主要是通过简单的sql语句来查询数据库,从而返回dataset,十分简单实用,有需要的小伙伴可以参考下。
    2015-06-06
  • 基于C#实现的仿QQ聊天工具的代码详解

    基于C#实现的仿QQ聊天工具的代码详解

    本文介绍了基于C#实现的仿QQ聊天工具的系统架构设计、核心功能模块、数据库设计、通信协议、界面实现、关键技术实现、部署与运维、扩展功能建议以及测试方案,需要的朋友可以参考下
    2026-02-02
  • C#打印PDF文档的10种方法(小结)

    C#打印PDF文档的10种方法(小结)

    这篇文章主要介绍了C#打印PDF文档的10种方法(小结),可分多种情况来进行,如设置静默打印、指定打印页码范围和打印纸张大小、双面打印、黑白打印等等,一共分成10种等,感兴趣的可以了解一下
    2019-04-04
  • 使用C#代码重新排列PDF页面的操作代码

    使用C#代码重新排列PDF页面的操作代码

    对于页面顺序混乱的 PDF 文档,重新排列页面可以避免读者产生困惑,同时也能让文档结构更加清晰有序,本文将演示如何使用 Spire.PDF for .NET 以编程方式重新排列现有 PDF 文档中的页面,需要的朋友可以参考下
    2025-12-12
  • 完美解决c# distinct不好用的问题

    完美解决c# distinct不好用的问题

    这篇文章主要介绍了完美解决c# distinct不好用的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • C#验证码问题的快速解决方法

    C#验证码问题的快速解决方法

    下面小编就为大家带来一篇C#验证码问题的快速解决方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-07-07
  • C#实现读取被进程占用的文件实现方法

    C#实现读取被进程占用的文件实现方法

    这篇文章主要介绍了C#实现读取被进程占用的文件实现方法,涉及C#进程操作及文件读取的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-08-08
  • C#中的正则表达式介绍

    C#中的正则表达式介绍

    关于正则表达式,我们都知道挺繁琐的。本文介绍的是C#中的正则表达式,希望对你有帮助,一起来看。
    2015-10-10
  • 深入分析C#连接Oracle数据库的连接字符串详解

    深入分析C#连接Oracle数据库的连接字符串详解

    本篇文章是对C#连接Oracle数据库的连接字符串进行了详细的分析介绍,需要的朋友参考下
    2013-05-05

最新评论