C# 为什么System.Drawing矩形、点、大小等是可变结构而不是类?
微软决定制作这些结构有什么原因吗 三者都是可变的。如果它们是不可变的,或者是引用类型,我会发现它们更容易处理 如果有理由它们必须是结构,为什么它们是可变的?为什么它们是结构 值语义C# 为什么System.Drawing矩形、点、大小等是可变结构而不是类?,c#,.net,design-decisions,C#,.net,Design Decisions,微软决定制作这些结构有什么原因吗 三者都是可变的。如果它们是不可变的,或者是引用类型,我会发现它们更容易处理 如果有理由它们必须是结构,为什么它们是可变的?为什么它们是结构 值语义 这些值的两个相同实例之间没有本质区别。具有坐标的任何点,[2,3]与具有相同坐标的任何其他点相等,就像具有相似值的任何两个int点相等一样。 这符合设计指南: 它在逻辑上表示单个值,类似于基元类型 (整数、双精度等) 性能 值类型分配和取消分配的成本更低 通常需要创建这些值的多个实例。结构的创建成本更低,如果它们是本
这些值的两个相同实例之间没有本质区别。具有坐标的任何
点
,[2,3]
与具有相同坐标的任何其他点相等,就像具有相似值的任何两个int
点相等一样。
这符合设计指南:
它在逻辑上表示单个值,类似于基元类型
(整数、双精度等)
性能
值类型分配和取消分配的成本更低
通常需要创建这些值的多个实例。结构的创建成本更低,如果它们是本地值,则将在堆栈上创建它们,从而减轻GC的压力
大小让我们考虑一下这些值的大小:
点
:8字节大小
:8字节矩形
:16字节
对于点
和大小
,它们的大小与对类实例的引用的大小相同,都是64位的
系统
引用微软的指导方针:
为什么它们是可变的
这些结构是完全可变的。这是为了性能而做的(违反指南),因为它避免了为修改操作创建新值的需要
关于评论中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
被装箱到对象
,以便提供迭代,并且您无法修改取消装箱转换的结果
,(感谢Rajeev)迭代器按值返回数据,您将只对值的副本进行更改
这很好:
for (int i = 0; i < points.Length; i++)
{
points[i].X += 1;
}
for(int i=0;i
Microsoft不需要将这些结构定义为类。
这些基本上都是小建筑
- 存储一组四个整数
- 表示整数x坐标和y坐标的有序对
- 存储一对有序整数
类
,对于点
结构,相同的坐标可以引用内存中的不同对象。定义为结构
,我们知道具有相同坐标的不同点之间没有差异。这意味着它们是值类型。值类型的分配几乎总是比较便宜。看看它们的大小
Point : 8 bytes
Size: 8 bytes
Rectangle: 16 bytes
谁想在每次创建
点(1,2)
时分配新的内存部分 你能详细说明他们的易变结构是如何引起你的问题的吗?@Damien_不信者举例:foreach(点中的点){r.X+=1;}
相关,可能重复:@DominicKexel,问题是相关的,虽然被接受的答案只与WPF有关。@Rotem这就是我没有投票关闭的原因:-)@RotemRectangle
根据该链接违反了微软四分之三的指导原则。@Andrew我同意!但我想,从逻辑上讲,这是一个大于其他几点的值。@Rotem我明白你的意思。也许问题应该是为什么它们是可变的?@JLRishe不,它们是可变的<例如,code>Rectangle有一个Offset
方法来更改其坐标。第三,对我来说,矩形
并不代表单个值,但我认为这是主观的:)@Andrew我错了。在这种情况下,我也觉得奇怪,它们是可变的。我已经撤销了先前的评论。