C#class vs struct

时间:2012-12-22 22:16:46

标签: c# class struct

Microsoft使用struct具有以下规则:

      

如果是实例,请考虑定义结构而不是类       类型很小,通常是短暂的或通常嵌入       其他对象。

      

除非类型具有以下所有特征,否则不要定义结构:

      
          
  1. 它逻辑上表示单个值,类似于基本类型(整数,双精度等)。
  2.       
  3. 实例大小小于16个字节。
  4.       
  5. 这是不可改变的。
  6.       
  7. 不必频繁装箱。
  8.            

据我所知,您需要一个值类型行为时创建struct。当然,这会在分配并将其传递给函数时为您提供复制开销。但是你为什么要关注#2和#3?如果您的价值类型太大会怎么样?而且,我不明白你为什么要将一个不可变类型作为一个值类型。如果类型是不可变的,那么最好通过引用节省传递它的时间,因为无论如何它都无法更改。

我问的原因是我正在制作一个游戏,其中对象具有Vector2d类型的Coordinates,Velocity等属性。问题是,我应该制作Vector2d不可变结构(不需要大量的额外内存吗?),可变结构(人们说它们是邪恶的)或只是类(我将不得不总是调用vector.Clone(),否则我可能会无意中得到两个具有相同向量变量的对象)

4 个答案:

答案 0 :(得分:2)

  

此外,我不明白为什么你会把不可变类型变成值类型。

int类型是一个不可变类型,是您需要不可变值类型的完美示例。

想象一下,如果int是引用类型。如果每次使用整数时都必须取消引用,那将是非常昂贵的。这实际上是当您使用“盒装”整数时发生的情况(例如存储在object类型的变量中的整数)。与Java相比,.NET的一个改进是集合可以保存未装箱的整数。

  

如果类型是不可变的,那么最好通过引用来节省传递它的时间

是的,如果它很大且不可变,那么你可以通过引用传递它来节省时间。这就是为什么指南建议大类型应该是参考类型。

答案 1 :(得分:1)

16字节似乎有点武断,但可能与典型CPU的缓存行大小有关。这比现代CPU上的64字节高速缓存线要小得多。可能是因为您无法将结构明确地对齐到一行。

保持您再次输入不可变性,避免了通过引用传递的需要。而只是返回一个新实例。以下引用比使用缓存值要昂贵得多,保持对象较小将增加它保留在缓存中的机会。

一般来说,如果你想要引用语义使它成为一个类,否则使它成为一个结构。我建议您遵循MS指南,除非您可以使用剖析器(或其他一些经验证据)证明有充分理由不这样做。

答案 2 :(得分:0)

对于#2,不应轻易复制大型结构,因此大部分时间都应该是大型结构。而且,这些并不是硬规则,只是经验法则。如果你有充分的理由不遵守规则,请继续。

答案 3 :(得分:-1)

  1. 当传递/操作结构时,必须将整个值复制到堆栈周围而不仅仅是引用。一旦达到一定的大小,16个字节,考虑使用一个类来避免开销。

  2. 不变性更多的是一种旨在减少代码错误的模式,而不是一种硬性规则。如果您的值类型可能是不可变的,那么这样做会很有帮助。

  3. 你可能误解了不变性。您的变量可以更改值,但值本身不会更改。例如,您可以拥有一个Datetime变量并将其设置为任何其他DateTime实例,但在初始化后,您无法实际更改实例的字段。