什么时候应该在C#中使用结构而不是类?我的概念模型是,当项只是值类型的集合时,使用结构。一种将它们逻辑地结合在一起的方法。
我在这里遇到了这些规则:
结构应表示单个价值结构应具有内存占用空间小于16字节。结构不应在之后更改创造
这些规则有效吗?结构在语义上意味着什么?
什么时候应该在C#中使用结构而不是类?我的概念模型是,当项只是值类型的集合时,使用结构。一种将它们逻辑地结合在一起的方法。
我在这里遇到了这些规则:
结构应表示单个价值结构应具有内存占用空间小于16字节。结构不应在之后更改创造
这些规则有效吗?结构在语义上意味着什么?
当前回答
结构是值类型。如果将结构分配给新变量,则新变量将包含原始变量的副本。
public struct IntStruct {
public int Value {get; set;}
}
执行以下操作将导致存储在内存中的结构的5个实例:
var struct1 = new IntStruct() { Value = 0 }; // original
var struct2 = struct1; // A copy is made
var struct3 = struct2; // A copy is made
var struct4 = struct3; // A copy is made
var struct5 = struct4; // A copy is made
// NOTE: A "copy" will occur when you pass a struct into a method parameter.
// To avoid the "copy", use the ref keyword.
// Although structs are designed to use less system resources
// than classes. If used incorrectly, they could use significantly more.
类是引用类型。将类分配给新变量时,该变量包含对原始类对象的引用。
public class IntClass {
public int Value {get; set;}
}
执行以下操作只会导致内存中类对象的一个实例。
var class1 = new IntClass() { Value = 0 };
var class2 = class1; // A reference is made to class1
var class3 = class2; // A reference is made to class1
var class4 = class3; // A reference is made to class1
var class5 = class4; // A reference is made to class1
结构可能会增加代码错误的可能性。如果将值对象视为可变引用对象,那么当所做的更改意外丢失时,开发人员可能会感到惊讶。
var struct1 = new IntStruct() { Value = 0 };
var struct2 = struct1;
struct2.Value = 1;
// At this point, a developer may be surprised when
// struct1.Value is 0 and not 1
其他回答
当您需要值语义而不是引用语义时,请使用结构。
如果需要引用语义,则需要类而不是结构。
类是引用类型。创建类的对象时,分配给该对象的变量只保留对该内存的引用。将对象引用指定给新变量时,新变量将引用原始对象。通过一个变量所做的更改反映在另一个变量中,因为它们都引用了相同的数据。结构是值类型。创建结构时,分配给该结构的变量保存该结构的实际数据。当将结构分配给新变量时,将复制该结构。因此,新变量和原始变量包含相同数据的两个单独副本。对一个副本所做的更改不会影响另一个副本。通常,类用于建模更复杂的行为,或在创建类对象后要修改的数据。结构最适合于主要包含在创建结构后不打算修改的数据的小型数据结构。
类和结构(C#编程指南)
无论何时:
不需要多态性,want值语义,以及希望避免堆分配和相关的垃圾收集开销。
然而,需要注意的是,结构(任意大)传递比类引用(通常是一个机器字)更昂贵,因此类在实践中可能会更快。
我认为一个好的第一近似值是“从不”。
我认为一个好的二次近似是“从不”。
如果你渴望表现,那么考虑一下,但始终要衡量。
简单地说,如果:
您的对象财产/字段不需要更改。我的意思是你只想给它们一个初始值,然后读它们。对象中的财产和字段是值类型,它们并没有那么大。
如果是这种情况,您可以利用结构来获得更好的性能和优化的内存分配,因为它们只使用堆栈,而不是同时使用堆栈和堆(在类中)