3

我正在构建一个应用程序,我需要处理图表中的位置。这个位置有X、Y的值和北、东、南、西的方向。我认为这个位置可能是Struct因为它代表该图中的单个值。

我研究并思考Structs并发现这些规则可以使用Struct

  • 它在逻辑上表示单个值,类似于原始类型(整数、双精度等)。
  • 它的实例大小小于 16 字节。
  • 它是不可变的。
  • 它不必经常装箱。

这是我未完成的示例Struct

public struct Position
{
   public long PositionX { get; set; }

   public long PositionY { get; set; }

   public CompassPoint CompassPoint { get; set; }
}

public enum CompassPoint : byte
{
   North,
   East,
   South,
   West
}

我想知道如何计算我的字节大小Struct以及如何知道它是否不可变?

谢谢。

更新:

好的。根据回复,我似乎Struct通过了 16 个字节,因为只有两个long有 16 个字节 + 1 个字节CompassPoint

Struct但是一个额外的问题是:使用16 字节且不可变的 a 我获得了什么?看看DateTime Struct,它似乎有超过 16 个字节?任何问题?

4

2 回答 2

6

大小取决于CompassPoint类型。但是,每个都long将使用 8 个字节,因此您已经超过了建议的最大 16 个字节。虽然这不是一个硬性规则,但你可能会得到比它是一个类更差的性能,这取决于你如何使用它。

结构的确切大小由 JIT 编译器确定,但通常您可以添加成员的大小来预测大小。小数据类型会被填充,所以如果你CompassPoint只使用一个字节,它仍然需要 4 或 8 个字节来使结构大小达到一个均匀的边界。

该结构不是不可变的,因为您可以更改其中的属性。将 setter 设为私有,并添加一个可以创建它以使其不可变的构造函数:

public struct Position {

  public long PositionX { get; private set; }
  public long PositionY { get; private set; }
  public CompassPoint CompassPoint { get; private set; }

  public Position(long x, long y, CompassPoint compass) {
    PositionX = x;
    PositionY = y;
    CompassPoint = compass;
  }

}
于 2012-08-29T00:49:48.797 回答
2

您可以使用Marshal.SizeOf 方法来获取结构的非托管大小(以字节为单位):

Position pos = new Position(); // this constructor call is not necessary for structs
int sizeInBytes = Marshal.SizeOf(pos);

但请注意,对象的非托管和托管大小有时会有所不同。

于 2012-08-29T01:02:02.383 回答