简体   繁体   English

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

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

Is there a reason Microsoft decided to make these structs?微软决定制作这些结构有什么原因吗?

All three are mutable.这三个都是可变的。 I would find them much easier to deal with if they were either immutable, or if they were reference types.如果它们是不可变的,或者如果它们是引用类型,我会发现它们更容易处理。

If there are reasons they must be structs, why are they mutable?如果有理由它们必须是结构体,为什么它们是可变的?

Why are they Structs为什么是结构体

Value Semantics值语义
There is no essential difference between two identical instances of these values.这些值的两个相同实例之间没有本质区别。 Any Point with coordinates, [2,3] is equal to any other point with the same coordinates, much like any two int s with similar value are equal.任何具有坐标的Point[2,3]等于具有相同坐标的任何其他点,就像任何两个具有相似值的int相等一样。 This is in conformance with the design guideline:这符合设计指南:

It logically represents a single value, similar to primitive types (integer, double, and so on).它在逻辑上表示单个值,类似于原始类型(整数、双精度等)。

Performance表现

Value types are cheaper to allocate and deallocate.分配和释放值类型的成本更低。

There is often requirement to create many instances of these values.通常需要创建这些值的许多实例。 Structs cost less to create, and if they are local values, they will be created on the stack, relieving pressure from the GC.结构体的创建成本较低,如果它们是本地值,它们将在堆栈上创建,从而减轻 GC 的压力。

Size尺寸
Let's consider the size of these values:让我们考虑这些值的大小:
Point : 8 bytes Point :8个字节
Size : 8 bytes Size :8 字节
Rectangle : 16 bytes Rectangle :16 字节

For Point and Size , their size is the same as a reference to a class instance would be in a 64-bit system.对于PointSize ,它们的大小与在 64 位系统中对类实例的引用相同。

Quotes taken from Microsoft's guidelines: Choosing Between Classes and Structures引自 Microsoft 指南: 在类和结构之间进行选择

Why are they Mutable为什么它们是可变的

These structs are fully mutable.这些结构是完全可变的。 This is done (against the guidelines) for the sake of performance, as it avoids the need to create new values for modification operations.这样做是为了性能(违反准则),因为它避免了为修改操作创建新值的需要。

Regarding the OP's code example in the comments:关于评论中的 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; 
}

The only reason this foreach fails, is because p is boxed to object in order to provide iteration, and you Cannot modify the result of an unboxing conversion , (thanks Rajeev) the iterator returns the data by value, and you would only be making changes to the copy of the value.这个foreach失败的唯一原因是因为p装箱object以提供迭代,并且您Cannot modify the result of an unboxing conversion (感谢 Rajeev)迭代器按值返回数据,您只会进行更改到值的副本

This works fine:这工作正常:

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

Microsoft doesn't need to define these structures as a class. Microsoft 不需要将这些结构定义为一个类。

These are basically small structures.这些基本上都是小型结构。

If these are defined as a class , for Point structure, same coordinates could refer to different objects in memory.如果这些被定义为一个class ,对于Point结构,相同的坐标可以引用内存中的不同对象。 Defining as a struct , we know there is no difference between different points with same coordinates.定义为struct ,我们知道具有相同坐标的不同点之间没有区别。 It means they are value types.这意味着它们是值类型。 Value types are almost always cheaper to allocate.分配值类型几乎总是更便宜。 Look at their size;看看它们的大小;

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

Who wants to allocate a new memory part every time they create a Point(1,2) ?谁想在每次创建Point(1,2)时分配一个新的内存部分?

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

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