胡建平 發表於 2026-1-9 10:09:57

C#中struct, class的使用区别

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>1.内存分配</li><li>2.类型存储方式</li><li>3.默认构造函数</li><li>4.垃圾回收与生命周期</li><li>5.继承</li><li>6.默认值</li><li>7.适用场景</li><li>8.传值与传引用</li><li>9.内存分配效率</li><li>10.示例代码</li><ul class="second_class_ul"><li>class示例:</li><li>struct示例:</li></ul><li>总结:</li><ul class="second_class_ul"></ul></ul></div><p>在 C# 中,<code>class</code> 和 <code>struct</code> 都用于定义数据类型,但它们在多个方面存在显著的差异。主要的区别体现在内存分配、生命周期、性能等方面。下面是它们的主要区别:</p>
<p class="maodian"></p><h2>1.内存分配</h2>
<ul><li><code>class</code>(类):类是引用类型。当创建一个类的实例时,内存分配在 堆 上(Heap)。在堆上分配的对象通常会由垃圾回收器(GC)自动管理生命周期。</li><li><code>struct</code>(结构体):结构体是值类型。当创建一个结构体的实例时,内存分配在 栈 上(Stack)。值类型的对象直接存储其值,而不是引用其他数据。</li></ul>
<p class="maodian"></p><h2>2.类型存储方式</h2>
<ul><li><code>class</code>:类对象存储的是对实际数据的引用(地址),即 引用类型。这意味着当多个变量引用同一个对象时,它们都指向同一块内存区域。</li><li><code>struct</code>:结构体存储的是实际的数据值,即 值类型。当结构体被赋值给另一个变量时,会复制整个结构体的内容,而不是引用原始结构体。</li></ul>
<p class="maodian"></p><h2>3.默认构造函数</h2>
<ul><li><code>class</code>:类可以有自定义构造函数,并且支持默认构造函数(如果没有显式定义构造函数,编译器会自动生成一个无参的构造函数)。</li><li><code>struct</code>:结构体也可以有自定义构造函数,但编译器会自动提供一个 无参数的默认构造函数,不能被重写。结构体的构造函数必须初始化所有字段。</li></ul>
<p class="maodian"></p><h2>4.垃圾回收与生命周期</h2>
<ul><li><code>class</code>:类对象的生命周期由垃圾回收器管理。当一个类实例没有任何引用指向它时,GC 会自动回收它。</li><li><code>struct</code>:结构体的生命周期通常由栈管理,超出作用域时自动销毁。由于结构体通常不在堆上分配内存,因此不需要垃圾回收器来管理其生命周期。</li></ul>
<p class="maodian"></p><h2>5.继承</h2>
<ul><li><code>class</code>:类支持继承,一个类可以继承自另一个类。类可以是基类,也可以是派生类。</li><li><code>struct</code>:结构体 不支持继承。结构体不能继承自其他结构体或类,但它们可以实现接口。</li></ul>
<p class="maodian"></p><h2>6.默认值</h2>
<ul><li><code>class</code>:类的实例默认初始化为 <code>null</code>,表示没有引用指向任何对象。</li><li><code>struct</code>:结构体默认初始化为该结构体类型的零值,所有字段的值都为默认值(例如,数值类型的字段为 <code>0</code>,布尔类型为 <code>false</code>)。</li></ul>
<p class="maodian"></p><h2>7.适用场景</h2>
<ul><li><code>class</code>:适用于需要共享数据、需要继承或需要复杂行为的场景。类可以包含复杂的状态和方法,通常用于管理资源(如数据库连接、文件操作等)。</li><li><code>struct</code>:适用于轻量级的数据结构,通常包含少量数据,且需要快速复制的场景。结构体一般用于表示较小的对象,如点、矩形、颜色等,不应包含过多的方法或复杂的行为。</li></ul>
<p class="maodian"></p><h2>8.传值与传引用</h2>
<ul><li><code>class</code>:类对象在传递给方法时,传递的是对象的引用,也就是说,方法内部对对象的修改会影响原始对象。</li><li><code>struct</code>:结构体在传递给方法时,传递的是值的副本,即方法内部对结构体的修改不会影响原始结构体。</li></ul>
<p class="maodian"></p><h2>9.内存分配效率</h2>
<ul><li><code>class</code>:类对象的内存分配较慢,因为它们是在堆上分配内存,并且需要由垃圾回收器管理生命周期。</li><li><code>struct</code>:结构体的内存分配较快,因为它们通常在栈上分配,且没有垃圾回收的开销。但如果结构体过大(包含很多字段),在栈上传递时可能会带来性能问题。</li></ul>
<p class="maodian"></p><h2>10.示例代码</h2>
<p class="maodian"></p><h3>class示例:</h3>
<div class="jb51code"><pre class="brush:csharp;">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"
    }
}
</pre></div>
<p>在这个例子中,<code>p1</code> 和 <code>p2</code> 引用了同一个 <code>Person</code> 对象。修改 <code>p2</code> 中的 <code>Name</code> 属性也会影响 <code>p1</code>,因为它们指向同一块内存。</p>
<p class="maodian"></p><h3>struct示例:</h3>
<div class="jb51code"><pre class="brush:csharp;">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
    }
}
</pre></div>
<p>在这个例子中,<code>p2</code> 是 <code>p1</code> 的副本,修改 <code>p2</code> 不会影响 <code>p1</code>,因为它们是值类型,赋值时会创建副本。</p>
<p class="maodian"></p><h2>总结:</h2>
<table><thead><tr><th>特性</th><th>class (引用类型)</th><th>struct (值类型)</th></tr></thead><tbody><tr><td>内存分配</td><td>堆</td><td>栈</td></tr><tr><td>生命周期管理</td><td>垃圾回收器管理</td><td>自动销毁(超出作用域时销毁)</td></tr><tr><td>是否支持继承</td><td>支持继承</td><td>不支持继承</td></tr><tr><td>默认值</td><td>null</td><td>所有字段初始化为零值</td></tr><tr><td>是否实现接口</td><td>可以实现多个接口</td><td>可以实现多个接口</td></tr><tr><td>赋值与传递</td><td>传递引用(引用类型)</td><td>传递值(复制数据)</td></tr><tr><td>适用场景</td><td>适用于较复杂的对象,涉及共享数据和继承的场景</td><td>适用于小型数据结构,要求高效的复制与传递的场景</td></tr><tr><td>内存效率</td><td>内存分配较慢,需要垃圾回收</td><td>内存分配较快,不涉及垃圾回收</td></tr></tbody></table>
<p>在选择使用 <code>class</code> 还是 <code>struct</code> 时,主要依据数据的大小、结构的复杂度、性能需求以及是否需要继承等因素。一般来说,如果对象的大小较大或需要复杂的行为,使用 <code>class</code>;如果是简单的数据结构并且需要高效的复制操作,可以使用 <code>struct</code>。</p>
<p>到此这篇关于C#中struct, class的使用区别的文章就介绍到这了,更多相关C# struct, class区别内容请搜索琼殿技术社区以前的文章或继续浏览下面的相关文章希望大家以后多多支持琼殿技术社区!</p>
                           
                            <div class="art_xg">
                              <b>您可能感兴趣的文章:</b><ul><li>C#基础教程之类class与结构struct的区别</li><li>C#中struct与class的区别详解</li><li>区分C# 中的 Struct 和 Class</li><li>C#中struct和class的区别详解</li></ul>
                            </div>

                        </div>
                        <!--endmain-->
頁: [1]
查看完整版本: C#中struct, class的使用区别