When should I use a struct instead of a class?msdn说当需要轻量级对象时应该使用结构。当结构比类更可取时,是否存在其他方案? 有些人可能忘记了: 我理解结构和类之间的技术差异,我只是不知道何时使用结构。 msdn有答案:在类和结构之间进行选择。 基本上,这一页给了你一个4项的清单,并说除非你的类型符合所有的标准,否则就使用一个类。
我很惊讶我没有读到之前的答案,我认为这是最重要的方面: 当我需要一个没有标识的类型时,我使用结构。例如,三维点:
如果您有这个结构的两个实例,那么您不关心它们是内存中的单个数据块还是两个。你只关心他们所拥有的价值。 比尔·瓦格纳在他的书《有效的C》(http://www.amazon.com/effective specific ways improve your/dp/0321245660)中对此有一章。他的结论是,使用以下原则:
当需要值类型语义而不是引用类型时,请使用结构。结构是按值复制的,所以要小心! 另请参见前面的问题,例如 .NET中的struct和class有什么区别? 我会在以下情况下使用结构: 对象应该是只读的(每次传递/分配一个结构时,它都会被复制)。当涉及多线程处理时,只读对象非常好,因为在大多数情况下,它们不需要重新请求锁定。 物体很小,寿命很短。在这种情况下,很有可能将对象分配到堆栈上,这比将其放在托管堆上要高效得多。更重要的是,一旦对象超出其作用域,它所分配的内存就会被释放。换句话说,垃圾收集器的工作更少,内存使用效率更高。 如果使用:
在以下情况下使用结构:
当我想将一些值组合在一起以便从方法调用中传递内容时,我总是使用结构,但在读取这些值之后,我不需要将其用于任何内容。就像保持清洁一样。我倾向于把结构中的事物看作是"一次性的",而把类中的事物看作是更有用和"实用的"。 如果一个实体是不可变的,那么使用结构或类的问题通常是性能问题而不是语义问题。在32/64位系统上,无论类中的信息量如何,类引用都需要存储4/8字节;复制类引用将需要复制4/8字节。另一方面,每个不同的类实例除了包含的信息和对它的引用的内存开销外,还将有8/16字节的开销。假设需要一个由500个实体组成的数组,每个实体包含四个32位整数。如果实体是结构类型,则无论500个实体是否都相同、都不同或介于两者之间,数组都将需要8000个字节。如果实体是类类型,500个引用的数组将占用4000个字节。如果这些引用都指向不同的对象,那么每个对象将需要额外的24个字节(所有500个对象需要12000个字节),总共需要16000个字节——是结构类型存储成本的两倍。另一方面,代码创建了一个对象实例,然后复制了对所有500个数组槽的引用,该实例的总开销为24字节,数组的总开销为4000字节,总共4024字节。一大笔节省。很少有情况能像最后一种情况一样有效,但在某些情况下,可能可以将一些引用复制到足够的阵列插槽中,以使这种共享变得有价值。 如果实体应该是可变的,那么是否使用类或结构的问题在某些方面更容易处理。假设"thing"是一个结构或类,它有一个名为x的整型字段,并执行以下代码:
是否希望后一个语句影响T1.X? 如果事物是一个类类型,T1和T2是等价的,这意味着T1.x和T2.x也是等价的。因此,第二条语句将影响T1.X。如果事物是结构类型,T1和T2将是不同的实例,这意味着T1.X和T2.X将引用不同的整数。因此,第二个语句不会影响T1.X。 可变结构和可变类具有根本不同的行为,尽管.NET在处理结构突变时有一些奇怪之处。如果需要值类型行为(即"t2=t1"将数据从t1复制到t2,同时将t1和t2保留为不同的实例),并且如果可以使用.NET对值类型处理中的怪癖,请使用结构。如果你想要值类型语义,但是.NET的怪癖会导致你的应用程序中的值类型语义被破坏,那么就使用一个类并含糊不清。 除此之外,上述优秀答案: 结构是值类型。 它们永远不会被设置为零。 将结构设置为"无",将其所有值类型设置为其默认值。 正如@simon所说,结构提供了"值类型"语义,因此如果您需要类似于内置数据类型的行为,请使用结构。因为结构是通过copy传递的,所以您需要确保它们的大小很小,大约16个字节。 当你真的不需要行为,但你需要比简单的数组或字典更多的结构。 跟进这就是我对结构的一般看法。我知道他们可以有方法,但我喜欢保持这种整体的精神差异。 结构在堆栈上,而不是堆上,因此它们是线程安全的,在实现传输对象模式时应该使用,您永远不希望使用堆上的对象,它们是易失的,在这种情况下,您希望使用调用堆栈,这是使用结构的基本情况,我对这里所有的答案感到惊讶, 隐马尔可夫模型。。。 我不会将垃圾收集用作支持/反对使用结构与类的参数。托管堆的工作原理与堆栈非常相似——创建对象只需将其放在堆的顶部,这几乎与在堆栈上分配一样快。另外,如果一个对象是短期的,并且在GC循环中不存在,那么释放是免费的,因为GC只使用仍然可以访问的内存。(搜索msdn,有一系列关于.NET内存管理的文章,我懒得去挖掘它们)。 大多数时候,我使用一个结构时,我会因为这样做而自责,因为后来我发现使用引用语义会使事情变得简单一点。 不管怎样,上面发表的msdn文章中的这四点似乎是一个很好的指导方针。 我认为最好的答案就是在需要属性集合时使用struct,在需要属性和行为集合时使用class。 |