繁体   English   中英

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

[英]Why are System.Drawing Rectangle, Point, Size etc mutable structs and not classes?

微软决定制作这些结构有什么原因吗?

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

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

为什么是结构体

值语义
这些值的两个相同实例之间没有本质区别。 任何具有坐标的Point[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)
{
    p.X += 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 不需要将这些结构定义为一个类。

这些基本上都是小型结构。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM