Font being immutable distresses both the programmer and the GC, because you need to create a new instance every time.
Why is Font an immutable reference type then?
It simplifies the usage from the render system.
If the framework were to allow Font to be mutable, it would need to detect changes, and rework how it's rendering happens on a regular basis. Since Font creates a native resource, keeping this immutable prevents the system from worrying about having to recreate handles internally on a repeated basis.
Also, I disagree in terms of "Distress to the programmer". By making Font immutable, it makes it more obvious what is happening when the user creates a Font object. If you want a new Font, you need to create a new Font object, which in turn creates new native font resources. Making Font immutable makes it more clear what is happening - you're less likely to create a performance problem accidentally.
Were Font mutable, it would be less obvious that you were creating handles repeatedly as you changed your Font properties.
Well, ask yourself some questions.
First, is a font logically a mutable thing, like a grocery list, or an immutable thing, like a number? If you are modelling a grocery list in a program, it makes sense to make it mutable because you typically think of having one grocery list the contents of which change as you run out of or purchase particular items. But numbers you typically model as being immutable -- the number 12 is the number 12, now and forever.
I think of "Helvetica 12 point bold" as being a fixed, immutable thing, like a number, not something I can change.
Second, is a font logically more like a value that you can make copies of, or is it more like a single thing that you can refer to? I don't think of having "two copies" of Helvetica; I think of referring to Helvetica. Whereas numbers I think of as having different copies of for different purposes -- when I have 12 items on my grocery list and 12 keys on my keyring, I don't think of both of those things as "referring to 12".
Since I think of fonts as being immutable and referred to, rather than as mutable and copied by value, I personally would model fonts as immutable reference types. Perhaps your intuitions about fonts are different than mine.
They aren't structures because they need to have finalizers to wrap the underlying objects and provide a sensible IDisposable implementation. What happens if you Dispose() your own copy of a struct? Do you clone the handle each time?
It isn't really much stress on the GC...
It also allows the Font to be re-used safely without worry about it changing half way through an operation ;-p
I disagree this distresses the programmer. There are plenty of immutable types in the BCL which are used on a daily basis by programmers and don't cause any issues. System.String for example.
One of the benefits of being immutable is that you don't have to create a new instance every time. You can re-use the same Font type as often as you like because it's not going to change. On the other hand, if it were mutable, you would need to make a copy every time to help guarantee that no one else changed it out from under you.
Lastly, Font is not actually an immutable class in the strictest sense of the word. It implements IDisposable and in the Dispose method tears down the underlying native object.
You could argue that it distresses the developer. But you could also make the same argument in the opposite case.
For example:
// Let me just set the button to the same font as the textbox...
button.Font = textBox.Font;
// ...except that I want the button's font to be bold.
button.Font.Bold = true;
The above code would set a button and a textbox's font to bold at the same time if Font were mutable, contrary to the developer's expectations.
Font is a poorly designed object, which violates the Single Responsibility Principle, and the difficulties you cite stem from this. The problem with Font is that it encompasses two things: (1) a description of how a font should be drawn, and (2) a GDI font object for a font with those properties. The former type could be mutable without consequence, while making the latter type mutable would pose all sorts of problems.
Among other things, consider the question of how one should track the ownership of a typical control (e.g Button) Font property? If one will sometimes change the fonts associated with controls, should one create a separate Font object for each control, and Dispose of it when changing a control's font to something else, or should one keep a list of all the different fonts one is using so as to avoid creating an excessive number of identical Font objects, or what?
If there existed a FontDescription struct (which was mutable, and not IDisposable) and things like Control.Font were of type FontDescription (or better yet, Control exposed a SetFont method with parameter of type FontDescription), the above question could be answered pretty simply. As it is, the most efficient approach for setting the Font of a control is to create a new font object (if one doesn't already have a suitable one), immediately Dispose it, and then do the assignment. The "font description" part of the Font remains quasi-valid even after Disposal, and that's all that's really needed for the Control.Font property.
来源:https://stackoverflow.com/questions/1561126/why-is-font-immutable