Структуры и открытые поля облегчат взаимодействие с некоторыми неуправляемыми API. Часто вы обнаружите, что низкоуровневый API хочет получить доступ к значениям по ссылке, что хорошо для производительности (так как мы избегаем ненужной копии). Использование свойств является препятствием для этого, и часто библиотеки-обертки делают копии для простоты использования, а иногда и для безопасности.
Из-за этого вы будете часто получать лучшую производительность, имея векторные и матричные типы, которые не имеют свойств, но имеют открытые поля.
Лучшие практики не создаются в вакууме. Несмотря на некоторый культ груза, в целом передовая практика существует по уважительной причине.
В этом случае у нас есть пара:
Свойство позволяет изменять реализацию без изменения клиентского кода (на двоичном уровне можно изменить поле на свойство без изменения клиентского кода на исходном уровне, однако оно будет компилироваться во что-то другое после изменения) , Это означает, что при использовании свойства с самого начала код, который ссылается на ваш, не нужно будет перекомпилировать просто для того, чтобы изменить то, что свойство делает внутренне.
Если не все возможные значения полей вашего типа являются допустимыми состояниями, то вы не хотите предоставлять их клиентскому коду, который его модифицирует. Таким образом, если некоторые комбинации значений недопустимы, вы хотите оставить поля закрытыми (или внутренними).
Я говорил код клиента. Это означает код, который вызывает ваш. Если вы не создаете библиотеку (или даже делаете библиотеку, но используете внутреннюю, а не публичную), вы обычно можете сойти с рук и с какой-то хорошей дисциплиной. В этой ситуации лучше всего использовать свойства, чтобы не позволить себе выстрелить себе в ногу. Более того, гораздо проще рассуждать о коде, если вы видите все места, где поле может измениться в одном файле, вместо того, чтобы беспокоиться о том, что оно модифицируется или нет, где-то еще. Фактически, свойства также хороши для установки точек останова, когда вы выясняете, что пошло не так.
Да, есть ценность видеть, что делается в промышленности. Тем не менее, у вас есть мотивация идти против лучших практик? или вы просто идете против лучших практик - усложняете работу кода - только потому, что это сделал кто-то другой? Ах, кстати, «другие делают это» - это то, как вы начинаете культ груза.
Итак ... Ваша игра работает медленно? Вам лучше посвятить время, чтобы выяснить узкое место и исправить это, вместо того, чтобы размышлять, что бы это могло быть. Вы можете быть уверены, что компилятор выполнит множество оптимизаций, поэтому есть вероятность, что вы смотрите не на ту проблему.
С другой стороны, если вы решаете, с чего начать, вам следует сначала позаботиться о том, какие алгоритмы и структуры данных, а не о мелких деталях, таких как поля и свойства.
Наконец, вы зарабатываете что-то, идя против лучших практик?
Для конкретных случаев (Unity и Mono для Android), Unity принимает значения по ссылке? Если этого не произойдет, он все равно скопирует значения, без увеличения производительности.
Если это так, если вы передаете эти данные в API, который принимает ref. Имеет ли смысл сделать поле общедоступным, или вы могли бы сделать тип способным напрямую вызывать API?
Да, конечно, могут быть оптимизации, которые вы можете сделать, используя структуры с открытыми полями. Например, вы получаете к ним доступ с помощью указателей Span<T>
или чего-то подобного. Они также компактны в памяти, что упрощает их сериализацию для отправки по сети или в постоянное хранилище (и да, это копии).
Теперь, если вы выбрали правильные алгоритмы и структуры, если они оказываются узким местом, тогда вы решаете, как лучше всего это исправить ... это может быть структура с открытыми полями или нет. Вы сможете беспокоиться об этом, если и когда это произойдет. Тем временем вы можете беспокоиться о более важных вещах, таких как создание хорошей или веселой игры, в которую стоит играть