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?
Yep, you're right, structs are not immutable. The thing about structs is that they are values. That means every variable is considered a copy, and its members are isolated from changes made to other variables. Structs are not copied on mutation.
A rectangle is defined by its Width, Height, and upper-left corner represented by the Location property. To draw rectangles, you need a Graphics object and a Pen object. The Graphics object provides the DrawRectangle method, and the Pen object stores features of the line, such as color and width.
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.
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.
Size
Let's consider the size of these values:Point
: 8 bytesSize
: 8 bytesRectangle
: 16 bytes
For Point
and Size
, their size is the same as a reference to a class instance would be in a 64-bit
system.
Quotes taken from Microsoft's guidelines: Choosing Between Classes and Structures
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:
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
,
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.Point Structure
represents an ordered pair of integer x- and y-coordinates.Size Structure
stores an ordered pair of integers.If these are defined as a class
, for Point
structure, same coordinates could refer to different objects in memory. Defining as a struct
, we know there is no difference between different points with same coordinates. 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)
?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With