[英]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?如果有理由它们必须是结构体,为什么它们是可变的?
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.对于
Point
和Size
,它们的大小与在 64 位系统中对类实例的引用相同。
Quotes taken from Microsoft's guidelines: Choosing Between Classes and Structures引自 Microsoft 指南: 在类和结构之间进行选择
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 (thanks Rajeev) the iterator returns the data by value, and you would only be making changes to the copy of the value.p
is boxed to object
in order to provide iteration, and you Cannot modify the result of an unboxing conversion
,这个
foreach
失败的唯一原因是因为 (感谢 Rajeev)迭代器按值返回数据,您只会进行更改到值的副本。p
被装箱为object
以提供迭代,并且您Cannot modify the result of an unboxing conversion
,
This works fine:这工作正常:
for (int i = 0; i < points.Length; i++)
{
points[i].X += 1;
}
These are basically small structures.这些基本上都是小型结构。
Rectangle Structure
stores a set of four integers. Rectangle Structure
存储一组四个整数。Point Structure
represents an ordered pair of integer x- and y-coordinates. Point Structure
表示一对有序的整数 x 和 y 坐标。Size Structure
stores an ordered pair of integers. Size Structure
存储一对有序的整数。 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.