Почему шрифт неизменяем?

неизменяемость шрифта огорчает как программиста, так и GC, потому что вам нужно каждый раз создавать новый экземпляр.

Почему шрифт является неизменяемым ссылочным типом?

6 ответов


Это упрощает использование системы визуализации.

Если бы фреймворк позволял шрифту быть изменяемым, ему нужно было бы обнаружить изменения и переработать, как это происходит на регулярной основе. Поскольку шрифт создает собственный ресурс, сохранение этого неизменяемого предотвращает беспокойство системы о необходимости повторного создания дескрипторов внутри системы.

кроме того, я не согласен с точки зрения "бедствия для программиста". Делая шрифт неизменяемым, это делает его более очевидно, что происходит, когда пользователь создает объект шрифта. Если вы хотите новый шрифт, вам нужно создать новый объект шрифта, который, в свою очередь, создает новые собственные ресурсы шрифта. Создание неизменяемого шрифта делает более понятным, что происходит - вы с меньшей вероятностью создадите проблему производительности случайно.

были изменяемыми шрифтами, было бы менее очевидно, что вы неоднократно создавали дескрипторы при изменении свойств шрифта.


Ну, задайте себе несколько вопросов.

во-первых, это шрифт логически изменчивая вещь, как список продуктов, или неизменяемая вещь, как число? Если вы моделируете список продуктов в программе, имеет смысл сделать его изменяемым, потому что вы обычно думаете о том, что один список продуктов, содержимое которого изменяется по мере того, как вы заканчиваете или покупаете определенные предметы. Но числа, которые вы обычно моделируете как неизменяемые-число 12-это число 12, сейчас и навсегда.

Я думаю о "Helvetica 12 point bold" как о фиксированной, неизменяемой вещи, такой как число, а не то, что я могу изменить.

во-вторых, это шрифт логически больше похоже на значение, которое вы можете сделать копии, или это больше похоже на то, что вы можете сослаться? Я не думаю о том, чтобы иметь "две копии" Helvetica; я думаю о том, чтобы ссылаться на Helvetica. В то время как числа, о которых я думаю, имеют разные копии для разных целей-когда у меня есть 12 элементов в моем списке покупок и 12 ключах на связке ключей я не думаю о обеих этих вещах как"ссылаясь на 12".

поскольку я считаю шрифты неизменяемыми и упоминаемыми, а не изменяемыми и копируемыми по значению, я лично моделировал бы шрифты как неизменяемые ссылочные типы. Возможно, ваша интуиция в отношении шрифтов отличается от моей.


они не являются структурами, потому что им нужны финализаторы для обертывания базовых объектов и обеспечения разумного IDisposable реализация. Что произойдет, если вы Dispose() ваша собственная копия A struct? Вы клонируете ручку каждый раз?

это не очень большой стресс для GC...

Он также позволяет Font быть повторно использованным безопасно без беспокойства о нем изменяя на полпути через деятельность ; - p


Я не согласен, это огорчает программиста. В BCL есть много неизменяемых типов, которые ежедневно используются программистами и не вызывают никаких проблем. Система.Например строка.

одним из преимуществ неизменяемости является то, что вам не нужно каждый раз создавать новый экземпляр. Вы можете повторно использовать тот же шрифт, как часто, как вам нравится, потому что он не изменится. С другой стороны, если бы он был изменяемым, вам нужно было бы делать копию каждый раз, чтобы помочь гарантировать, что никто не изменил его из-под вас.

наконец, шрифт на самом деле не является неизменяемым классом в самом строгом смысле этого слова. Он реализует IDisposable и в методе Dispose разрывает базовый собственный объект.


вы можете утверждать, что это огорчает разработчика. Но вы можете привести тот же аргумент и в обратном случае.

например:

// 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;

в приведенном выше коде кнопка и шрифт текстового поля будут выделены жирным шрифтом одновременно, если Font были изменчивы, вопреки ожиданиям разработчика.


шрифт-плохо спроектированный объект, который нарушает принцип единой ответственности, и трудности, которые вы цитируете, вытекают из этого. Проблема с шрифтом заключается в том, что он включает в себя две вещи: (1) описание того, как шрифт должен быть нарисован, и (2) Объект шрифта GDI для шрифта с этими свойствами. Первый тип может быть изменяемым без последствий, в то время как изменение второго типа создаст всевозможные проблемы.

среди прочего, рассмотреть вопрос о как следует отслеживать владение типичным контролем (e.кнопка g) свойство шрифта? Если иногда будут меняться шрифты, связанные с элементами управления, следует ли создавать отдельный объект шрифта для каждого элемента управления и утилизировать его при изменении шрифта элемента управления на что-то другое, или следует сохранить список всех разных шрифтов, которые используются, чтобы избежать создания чрезмерного количества одинаковых объектов шрифта, или что?

Если существовала структура FontDescription (которая была mutable, а не IDisposable) и такие вещи, как контроль.Шрифт был типа FontDescription (или еще лучше, Control выставил метод SetFont с параметром типа FontDescription), на вышеуказанный вопрос можно было ответить довольно просто. Как бы то ни было, наиболее эффективным подходом к настройке шрифта элемента управления является создание нового объекта шрифта (если у него еще нет подходящего), немедленно его утилизировать, а затем выполнить назначение. Часть" описание шрифта " шрифта остается квази-допустимой даже после утилизации, и это все, что действительно нужно для контроля.Свойство font.