为什么System.Drawing Rectangle,Point,Size等可变结构而不是类?
微软是否有理由决定制作这些结构?
这三个都是可变的。 如果它们是不可变的,或者它们是引用类型,我会发现它们更容易处理。
如果有理由它们必须是结构,为什么它们是可变的?
他们为什么要结构
价值语义
这些值的两个相同实例之间没有本质区别。 具有坐标[2,3]
任何点等于具有相同坐标的任何其他点,就像任何两个具有相似值的int
相等。 这符合设计准则:
它逻辑上表示单个值,类似于基本类型(整数,双精度等)。
性能
值类型分配和释放更便宜。
通常需要创建这些值的许多实例。 结构的成本较低,如果它们是本地值,它们将在堆栈上创建,从而减轻GC的压力。
尺寸
让我们考虑这些值的大小:
Point
:8个字节
Size
:8个字节
Rectangle
:16个字节
对于Point
和Size
,它们的大小与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
失败的唯一原因是因为 (感谢Rajeev)迭代器按值返回数据,你只会进行更改到价值的副本 。 p
被装箱 object
以提供迭代,并且你Cannot modify the result of an unboxing conversion
,
这很好用:
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)
时分配一个新的内存部分?