C#中类与结构的区别实例分析

蓝鲸
蓝鲸
发布时间:2026-10-13 | 4人浏览过
原创

C#程序设计中最基础的数据类型分类便是类与结构。初学者常因混淆二者的内存模型而难以把握其特性。本文将从概念原理出发,通过具体的代码对比实验,清晰呈现类作为引用类型与结构作为值类型在数据传输和状态修改上的本质差异。

基本概念区分

在C#的内存管理机制中,类与结构属于不同的类型体系,这直接决定了它们在内存中的布局和行为:

  • 类(Class):引用类型。实例通常存储在托管堆(Heap)中,而变量本身(栈上)存储的是指向该对象的引用地址。在进行方法调用或变量赋值时,传递的是这个引用地址。因此,若修改了通过引用指向的对象内部属性,原对象也会受到影响。这种方式在大数据量传输时消耗内存较小,因为只传递了一个指针。
  • 结构(Struct):值类型。其实例通常直接在栈(Stack)上分配(除非它是类的字段),或者内联嵌入在其他对象中。当进行赋值操作时,系统会创建一个完整的对象副本。这意味着对副本属性的修改不会影响到原始对象。由于涉及整个数据的拷贝,对于大型数据结构,这种传输方式会消耗更多的内存。

代码实例验证

为了直观展示上述理论,我们构建一个包含类和结构定义的测试程序。主要步骤包括声明对象、赋值、通过新变量关联并修改属性,最后观察原变量的变化。

第1步:定义数据容器

首先定义两个简单的类型,分别用于存放整型和字符串数据,以便观察赋值过程。

public class TestClass
{
    public int x;
    public string y;
}

public struct TestStruct
{
    public int x;
    public string y;
}

第2步:执行类(Class)的赋值与修改测试

创建 TestClass 实例 TC1 并赋予初值。接着将 TC1 赋值给 TC2,此时 TC2 引用的是同一个堆对象。修改 TC2 的值后,再次打印 TC1 的状态。

// 声明类对象 TC1 并赋值
testClass TC1 = new TestClass();
TC1.x = 10;
TC1.y = "10";
Console.WriteLine("TC1: x={0}, y={1}", TC1.x, TC1.y);

// 执行类传递:TC2 指向 TC1 的地址
testClass TC2 = TC1;
TC2.x = 20; // 修改副本引用的对象
TC2.y = "20";

Console.WriteLine("TC1: x={0}, y={1}", TC1.x, TC1.y); 
Console.WriteLine("TC2: x={0}, y={1}", TC2.x, TC2.y); 

现象说明:由于是引用类型,TC2 获得的是 TC1 的“钥匙”。修改 TC2 的内容实际上修改了内存中那个唯一的对象,因此 TC1 的值也会随之改变。

第3步:执行结构(Struct)的赋值与修改测试

使用完全相同的逻辑处理 TestStruct。声明 TS1 并赋值,然后将 TS1 赋值给 TS2。TS2 将获得 TS1 的一份完整快照。修改 TS2 的值后,再次打印 TS1 的状态。

// 声明结构对象 TS1 并赋值
TestStruct TS1 = new TestStruct();
TS1.x = 10;
TS1.y = "10";
Console.WriteLine("TS1: x={0}, y={1}", TS1.x, TS1.y);

// 执行结构传递:TS2 是 TS1 的独立副本
TestStruct TS2 = TS1;
TS2.x = 20; // 仅修改副本
TS2.y = "20";

Console.WriteLine("TS1: x={0}, y={1}", TS1.x, TS1.y); 
Console.WriteLine("TS2: x={0}, y={1}", TS2.x, TS2.y); 

第4步:运行结果与分析

编译并运行上述代码,控制台输出将清晰显示出两者的行为差异。如下方截图所示,类对象修改后的联动效应与结构对象的互不干扰形成了鲜明对比。

总结:以上代码的运行结果证明了引用类型与值类型的核心区别。在实际开发中,若需要频繁交换数据且追求性能,小型数据可考虑使用结构;若需要共享同一状态或通过继承扩展功能,则必须使用类。

以上就是C#中类与结构的区别实例分析的详细内容,更多关于C#编程基础资料的关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表