MSDN说你应该在需要轻量级对象时使用结构.当结构比类更可取时,还有其他任何情况吗?
有些人可能忘记了:
结构可以有方法.
结构不能被继承.
我理解结构和类之间的技术差异,我只是对使用结构时没有很好的感觉.
MSDN的答案是: 在类和结构之间进行选择.
基本上,该页面为您提供了一个4项清单,并说除非您的类型符合所有条件,否则使用类.
除非类型具有以下所有特征,否则不要定义结构:
它逻辑上表示单个值,类似于基本类型(整数,双精度等).
它的实例大小小于16个字节.
这是不可改变的.
它不必经常装箱.
我很惊讶我没有读过任何前面的答案,我认为这是最重要的方面:
当我想要一个没有身份的类型时,我使用结构.例如3D点:
public struct ThreeDimensionalPoint { public readonly int X, Y, Z; public ThreeDimensionalPoint(int x, int y, int z) { this.X = x; this.Y = y; this.Z = z; } public override string ToString() { return "(X=" + this.X + ", Y=" + this.Y + ", Z=" + this.Z + ")"; } public override int GetHashCode() { return (this.X + 2) ^ (this.Y + 2) ^ (this.Z + 2); } public override bool Equals(object obj) { if (!(obj is ThreeDimensionalPoint)) return false; ThreeDimensionalPoint other = (ThreeDimensionalPoint)obj; return this == other; } public static bool operator ==(ThreeDimensionalPoint p1, ThreeDimensionalPoint p2) { return p1.X == p2.X && p1.Y == p2.Y && p1.Z == p2.Z; } public static bool operator !=(ThreeDimensionalPoint p1, ThreeDimensionalPoint p2) { return !(p1 == p2); } }
如果你有这个结构的两个实例,你不关心它们是内存中的单个数据还是两个.你只关心他们持有的价值.
Bill Wagner在他的"有效的c#"(http://www.amazon.com/Effective-Specific-Ways-Improve-Your/dp/0321245660)一书中有一章.他最后使用以下原则:
类型数据存储的主要责任是什么?
它的公共接口是否完全由访问或修改其数据成员的属性定义?
你确定你的类型永远不会有子类吗?
你确定你的类型永远不会被多态化处理吗?
如果对所有4个问题回答"是":使用结构.否则,请使用课程.
当您需要值类型语义而不是引用类型时,请使用结构.结构是按值复制的,所以要小心!
另见前面的问题,例如
.NET中struct和class之间有什么区别?
我会在以下情况下使用结构:
一个对象应该是只读的(每次传递/分配它被复制的结构).在多线程处理方面,只读对象很棒,因为在大多数情况下它们不需要锁定.
一个物体很小而且寿命短.在这种情况下,很有可能在堆栈上分配对象,这比将其放在托管堆上要有效得多.一旦超出其范围,对象分配的内存将被释放.换句话说,垃圾收集器的工作量较少,内存使用效率更高.
使用类如果:
它的身份很重要.在通过值传递给方法时,结构会隐式复制.
它将占用大量内存.
它的字段需要初始化器.
您需要从基类继承.
你需要多态行为;
使用结构如果:
它将像一个原始类型(int,long,byte等).
它的内存占用量必须很小.
您正在调用P/Invoke方法,该方法需要按值传递结构.
您需要减少垃圾收集对应用程序性能的影响.
其字段只需初始化为默认值.对于数字类型,此值为零,对于布尔类型,该值为false,对于引用类型,该值为null.
请注意,在C#6.0中,结构可以有一个默认构造函数,可用于将struct的字段初始化为非默认值.
您不需要从基类继承(除了ValueType,所有结构都从该类继承).
您不需要多态行为.
当我想将一些值组合在一起以便从方法调用中返回时,我总是使用一个结构体,但是在读完这些值后我不需要使用它.只是一种保持清洁的方法.我倾向于将结构中的东西视为"一次性"而类中的东西更有用且"功能性"