Почему шрифт неизменен? - PullRequest
       21

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

12 голосов
/ 13 октября 2009

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

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

Ответы [ 6 ]

29 голосов
/ 13 октября 2009

Упрощает использование из системы рендеринга.

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

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

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

14 голосов
/ 13 октября 2009

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

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

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

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

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

8 голосов
/ 13 октября 2009

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

Это не так уж много стресса для ГК ...

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

4 голосов
/ 13 октября 2009

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

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

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

0 голосов
/ 21 октября 2011

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

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

Если бы существовала структура FontDescription (которая была изменяемой, но не IDisposable) и такие вещи, как Control.Font имели тип FontDescription (или, что еще лучше, Control предоставлял метод SetFont с параметром типа FontDescription), вопрос выше может быть ответил довольно просто. Как таковой, наиболее эффективный подход для установки шрифта элемента управления заключается в создании нового объекта шрифта (если у него еще нет подходящего объекта), немедленном его удалении и последующем назначении. Часть «Описание шрифта» шрифта остается квази-допустимой даже после удаления, и это все, что действительно необходимо для свойства Control.Font.

0 голосов
/ 01 февраля 2011

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

Например:

// 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 будет изменяемым, вопреки ожиданиям разработчика.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...