首页 文章

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

提问于
浏览
14

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

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

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

2 回答

  • 2

    为什么他们是结构

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

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

    Performance

    值类型分配和取消分配更便宜 .

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

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

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

    微软指南引用的行情:Choosing Between Classes and Structures

    为什么它们是可变的

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

    关于评论中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)迭代器按值返回数据,你只会进行更改到 Value 的副本 .

    这很好用:

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

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

    这些基本上都是小结构 .

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

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

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

相关问题