c# 如何在类(class)和结构体(struct)之间做选择

本文探讨了C#中类(引用类型)与结构体(值类型)的区别及选择依据,包括它们的内存分配方式、数组分配的效率、装箱与拆箱的影响等关键因素。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文

c# 如何在类(class)和结构体(struct)之间做选择

所有的框架设计者面临的一个基本的设计决定是设计一个类类型(引用类型)还是一个结构体类型(值类型)。深入理解引用类型和值类型在行为上的不同对做出选择是至关重要的。

我们要考虑的引用类型和值类型的第一个不同之处在于,引用类型是分配到堆上的并且能够垃圾回收,而值类型是分配到栈上的或者在包含它的类型中呈串联的,并且当栈释放或者包含结构体的类型释放,结构体也被释放。

引用类型的数组分配是非直线的,意味着数组中的元素只是存放在堆中引用类型的实例的引用。值类型数组的分配是直线的,意味着数组中的元素是值类型的真实的实例。因此,值类型数组的分配和释放开销比引用类型的数组更加的低。另外,多数情况下值类型数组表现比局部引用好很多。

另一个不同点涉及到内存的使用。当值类型转换成引用类型或者转换成它实现的一个借口时要装箱。当转换回值类型时要拆箱。因为装箱后的箱子是对象要分配在堆上且能垃圾回收,过多的装箱和拆箱对堆、垃圾回收器有消极的影响,最终影响到程序的性能。相比之下,引用类型的转换不存在装箱。

引用类型的赋值复制的是引用,而值类型的赋值是赋值是复制所有的值。因此,大型的引用类型的赋值开销要比大型的值类型要低。

最后,引用类型传递的是引用,而值类型传递的是值。一个引用类型的实例的改变将会影响到所有指向这个实例的应用。值类型的实例传递时是通过复制值。一个值类型的实例的改变,当然不会影响它的副本。因为,当参数传递时或者返回值时,隐式地生成副本而不用使用者显示地生成副本,值类型可以被改变,会使很多使用者感到困惑。因此,值类型应该是持久不变的。

一般情况下,一个框架里的主要类型应该是类。然而,在一些情况下,值类型的特性表明用结构体更加合适。


使用:如果类型的实例小并且通常生命周期短或者通常嵌入到其它对象中,要考虑使用结构体而不是类。

避免使用:如果要定义的类型不是满足一下所有条件,就不要定义为结构体类型:

  • 逻辑上代表一个值,和原始类型相似(int, double等等)
  • 实例大小小于16个字节
  • 值持久不变
  • 不用频繁装箱
    在其它所有情况下,你都应该定义为类类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值