Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
252 views
in Technique[技术] by (71.8m points)

c# - 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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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 ints 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 bytes
Size: 8 bytes
Rectangle: 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

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:

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.

This works fine:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...