什么时候应该在C#中使用结构而不是类?我的概念模型是,当项只是值类型的集合时,使用结构。一种将它们逻辑地结合在一起的方法。

我在这里遇到了这些规则:

结构应表示单个价值结构应具有内存占用空间小于16字节。结构不应在之后更改创造

这些规则有效吗?结构在语义上意味着什么?


当前回答

除了常见的性能差异之外,让我再补充一个方面,那就是默认值的使用意图。

如果其字段的默认值不表示建模概念的合理默认值,请不要使用结构。

Eg.

即使所有字段都设置为默认值,“颜色”或“点”也有意义。RGB 0,0,0是一种非常好的颜色,(0,0)作为2D中的点也是如此。但是Address或PersonName没有合理的默认值。我的意思是,你能理解FirstName=null和LastName=null的PersonName吗?

如果你用一个类实现了一个概念,那么你可以强制执行某些不变量,例如一个人必须有名字和姓氏。但对于结构,总是可以创建一个实例,将其所有字段设置为默认值。

因此,当对没有合理默认值的概念进行建模时,更喜欢类。类的用户会明白null意味着没有指定PersonName,但如果您给他们一个PersonName结构实例,并将其所有财产设置为null,他们会感到困惑。

(通常的免责声明:性能考虑可能会凌驾于此建议之上。如果您有性能问题,请在决定解决方案之前进行衡量。试试BenchmarkDotNet,这很好!)

其他回答

在需要使用StructLayoutAttribute显式指定内存布局(通常用于PInvoke)的情况下,需要使用“结构”。

编辑:注释指出,可以将类或结构与StructLayoutAttribute一起使用,这当然是正确的。在实践中,您通常会使用一个结构——它是在堆栈上分配的,而不是在堆上分配的——如果您只是向非托管方法调用传递一个参数,这是有意义的。

结构在大多数方面类似于类/对象。结构可以包含函数、成员,并且可以继承。但C#中的结构仅用于数据保存。结构比类占用更少的RAM,并且垃圾收集器更容易收集。但当您在结构中使用函数时,编译器实际上采用的结构与类/对象非常相似,所以如果您想要使用函数,请使用类/对象。

类是引用类型。创建类的对象时,分配给该对象的变量只保留对该内存的引用。将对象引用指定给新变量时,新变量将引用原始对象。通过一个变量所做的更改反映在另一个变量中,因为它们都引用了相同的数据。结构是值类型。创建结构时,分配给该结构的变量保存该结构的实际数据。当将结构分配给新变量时,将复制该结构。因此,新变量和原始变量包含相同数据的两个单独副本。对一个副本所做的更改不会影响另一个副本。通常,类用于建模更复杂的行为,或在创建类对象后要修改的数据。结构最适合于主要包含在创建结构后不打算修改的数据的小型数据结构。

类和结构(C#编程指南)

除了运行时直接使用的值类型和其他用于PInvoke的值类型之外,您只能在两种情况下使用值类型。

当您需要复制语义时。当您需要自动初始化时,通常在这些类型的数组中。

我的规则是

1、始终使用类;

如果有任何性能问题,我会根据@IAbstract提到的规则将一些类更改为结构,然后进行测试,看看这些更改是否可以提高性能。