我正在做课程3354(在.NET Framework 2.0中实现系统类型和接口),据说对于简单的类,使用成员变量和函数,最好使用结构而不是类,因为开销
我从未听说过这样的事情,这种说法的有效性是什么?
答案 0 :(得分:12)
我建议从不使用结构,除非你有一个非常具体的用例,并且确切知道结构将如何使系统受益。
虽然C#结构确实允许成员,但它们的工作方式与类不同(不能是子类型,没有虚拟调度,可能完全存在于堆栈中)并且行为会根据提升而改变等等(提升是将价值类型推广到堆中的过程 - 出乎意料!)
所以,回答这个问题:我认为C#中最大的误解之一就是使用结构“来表现”。造成这种情况的原因是“开销”无法真正衡量,如果没有看到它与系统的其他部分如何相互作用以及角色,如果有任何值得注意的话,它就会起作用。这需要进行分析,不能用“减少开销”等简单的陈述来概括。
结构值类型有一些好的个案 - 一个例子是存储在图像数组中的复合RGB值。这是因为RGB类型很小,图像中可以有很多非常,数值类型可以很好地打包在数组中,并且可以帮助保持更好的内存局部性等。
答案 1 :(得分:9)
出于性能原因,您通常不应将应该是类的类型更改为结构。结构和类具有不同的语义,并且不完全可互换。确实,结构有时可以更快,但它们有时也可能更慢。它们的行为不同,您应该知道何时使用其中一种。
MSDN在choosing between classes and structures上有一个页面。
摘要是:
除非是,否则不要定义结构 type具有以下所有内容 特性:
- 它逻辑上表示单个值,类似于原始类型 (整数,双精度等)。
- 实例大小小于16个字节。
- 这是不可改变的。
- 不必频繁装箱。
有时可能会出现类型确实应该是类的情况,但出于性能原因,您需要将其作为结构。这很少见,你应该确保在走这条路线之前知道自己在做什么。如果你打破结构的不变性指南,那么这可能会特别危险。可变结构的行为方式可能是大多数程序员不期望的。
答案 2 :(得分:8)
当C#处于测试阶段时,我接受了对类和结构之间差异的演示。开发人员已经构建了一个Mandelbrot集查看器,它可以研究很多复杂的数字来完成它的结果。在第一个例子中,他们运行代码,复杂的数字表示为具有Real和Imaginary字段的类。然后,他们将单词class
更改为struct
并重新编译。性能差异很大。
在这种情况下,不必分配堆对象也不必对其进行垃圾收集,这就是产生差异的原因。根据您拥有的物体数量,差异可能或多或少都很大。在开始调整之前,请测量您的表现,然后再决定是否使用值类型。
答案 3 :(得分:2)
你将在95%的时间内使用课程。价值类型语义最终会让你陷入困境,而不是在路上。
但是,如果你要使用结构,请确保它是不可变的。
答案 4 :(得分:1)
在C#中,类和结构是完全不同的野兽。两者的语法几乎相同,但行为完全不同(引用与值)。结构的单个实例将使用比等效类更少的内存,但是一旦开始构建集合或传递它们,值类型语义将在性能方面(以及可能的内存消耗取决于您正在做的事情)杀死您,除非结构中的数据非常小。我不知道硬数是多少,但我们谈的是8字节或更少的数量级。
它在可维护性和可读性方面也会受到影响,因为这两者看起来很相似,但行为却截然不同。
答案 5 :(得分:1)
你可以遵循的一条经验法则是问自己你要做的事情是System.Date
如果不是,那么你真的应该质疑你的决定使用结构。
答案 6 :(得分:0)
struct是值类型,类是引用类。这可能是其中一个原因。
答案 7 :(得分:0)
对于你将拥有其中许多类型的简单类型,不需要继承,并且是不可变的良好候选者,结构是一个不错的选择。例如,Point,Rectangle,Decimal和DateTime。
如果你不会有很多,那么开销是无关紧要的,它不应该影响你的决定。如果你需要从它派生(或使它成为派生类型),它必须是一个类。如果该项不能是不可变的,那么struct不是一个好的候选者,因为改变一个实例不会改变它的任何副本。
答案 8 :(得分:0)
我认为最常引用的收支平衡点是结构中大约12个字节的数据。例如,3个整数。值类型和引用类型之间的区别更为重要,您应该根据成员很少的类型做出选择。
如果事情很重要,那么上课:)
答案 9 :(得分:0)
结构是值类型,类是引用类型。因此,如果您要传递引用,那么类可以在性能方面更好,因为您复制的是地址而不是整个结构。但是,如果要多次实例化和引用这些对象,结构将更好地执行,因为它们是在堆栈上分配的。因此,对于性能很重要的众多对象或需要值类型语义的小对象,结构可能更好。结构也没有默认构造函数。它们继承自Object,但除此之外它们都是无继承的。
答案 10 :(得分:-1)
无需分配/解除分配结构。