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这就是我没有投票关闭的原因:-)@Rotem
Rectangle
根据该链接违反了微软四分之三的指导原则。@Andrew我同意!但我想,从逻辑上讲,这是一个大于其他几点的值。@Rotem我明白你的意思。也许问题应该是为什么它们是可变的?@JLRishe不,它们是可变的<例如,code>Rectangle
有一个
Offset
方法来更改其坐标。第三,对我来说,
矩形
并不代表单个值,但我认为这是主观的:)@Andrew我错了。在这种情况下,我也觉得奇怪,它们是可变的。我已经撤销了先前的评论。