为什么System.Drawing Rectangle,Point,Size等可变结构而不是类?

微软是否有理由决定制作这些结构?

这三个都是可变的。 如果它们是不可变的,或者它们是引用类型,我会发现它们更容易处理。

如果有理由它们必须是结构,为什么它们是可变的?

他们为什么要结构

价值语义
这些值的两个相同实例之间没有本质区别。 具有坐标[2,3]任何点等于具有相同坐标的任何其他点,就像任何两个具有相似值的int相等。 这符合设计准则:

它逻辑上表示单个值,类似于基本类型(整数,双精度等)。

性能

值类型分配和释放更便宜。

通常需要创建这些值的许多实例。 结构的成本较低,如果它们是本地值,它们将在堆栈上创建,从而减轻GC的压力。

尺寸
让我们考虑这些值的大小:
Point :8个字节
Size :8个字节
Rectangle :16个字节

对于PointSize ,它们的大小与64位系统中类实例的引用相同。

根据Microsoft的指导原则引用: 在类和结构之间进行选择

为什么他们是可变的

这些结构是完全可变的。 为了性能,这是完成的(违反指南),因为它避免了为修改操作创建新值的需要。

关于评论中OP的代码示例:

 Point[] points = new Point[] { new Point(0,0), new Point(1,1), new Point(2,2) }; foreach (Point p in points) { pX += 1; } 

这个foreach失败的唯一原因是因为p装箱 object以提供迭代,并且你Cannot modify the result of an unboxing conversion (感谢Rajeev)迭代器按值返回数据,你只会进行更改到价值的副本

这很好用:

 for (int i = 0; i < points.Length; i++) { points[i].X += 1; } 

Microsoft不需要将这些结构定义为类。

这些基本上都是小结构。

  • Rectangle Structure存储一组四个整数。
  • Point Structure表示整数x和y坐标的有序对。
  • Size Structure存储一对有序的整数。

如果将这些定义为class ,则对于Point结构,相同的坐标可以引用内存中的不同对象。 定义为struct ,我们知道具有相同坐标的不同点之间没有区别。 这意味着它们是价值类型。 分配价值类型几乎总是更便宜。 看看他们的大小;

 Point : 8 bytes Size: 8 bytes Rectangle: 16 bytes 

谁想在每次创建Point(1,2)时分配一个新的内存部分?