Работать в C# с Equals и GetHashCode по многим причинам непросто, даже несмотря на наличие разного рода инструментов. Особенно по сравнению с тем, как это могло бы быть в нормально спроектированном ЯП, к которым, к большому сожалению, C#, в данном контексте, не относится. Если вам интересно, что это за проблемы, для чего этот метод вообще нужен, почему этот механизм реализован именно так, а не как-то иначе, как можно было сделать лучше, то добро пожаловать под кат.
Записи в категории C#
Новые возможности C# 8
Прошло примерно пол года с момента выхода C# 8, думаем самое время кратко рассмотреть основные нововведения. И начнем мы, пожалуй, по идее, с самого значимого из них, а именно с Nullable reference types.
Nullable reference types
Если бы Microsoft и компания писали бы сочинение по русскому языку в 5-ом классе, то обязательно бы получили минус полбалла за тавтологию, причем заслуженно. Дело в том, что reference types (ссылочные типы) по определению nullable, т.е. зануляемые, таким образом получается масло масляное. Кроме того, название этого функционала пересекается с уже имеющимся функционалом, а именно с Nullable value types. А так как эти возможности имеют мало общего , это приводит к небольшой неразберихе. И даже больше, не только названия пересекаются, но и синтаксис полностью идентичен, что с одной стороны, конечно, хорошо, но вот с другой… Основная цель этого нововведения — решить (а по факту получается «решить») крайне неприятную и старую, как мир, проблему The Billion Dollar Mistake, т.е. всем известную проблему с Null Pointer Exception. В современных и мейнстрим языках, на наш взгляд, подобной проблемы существовать не должно вовсе, но, по тем или иным причинам, большиство популярных языков программирования продолжают гордо нести дух старой школы, а вместе с тем и весь тот груз, с которым каждому разработчику приходится бороться ежедневно, как будто бы других проблем у разработчиков больше нет. Ошибки дизайнеров, допущенные при укладке фундамента в самом начале, и необходимость в обратной совместимости теперь и не дают шанса на исправление подобных ошибок на корню. Из-за чего мы и получаем то, что имеем, как бы грустно это ни было. Напомним, что первая версия C# вышла в далеком 2002 году. С учетом того, что текущая версия вышла в прошлом году, не трудно подсчитать, что на то, чтобы начать (подчеркнем, не побороть, а именно начать) бороться с проблемой, которой быть в принципе не должно, потребовалось невообразимых 17 лет.
Чтобы начать пользоваться Nullable Reference Types, необходимо одним из возможных способов включить эту функцию вручную. И если для старых проектов это оправдано, то почему не включить эту функцию для новых проектов? Остается только гадать. Активировать эту возможность можно как для проекта целиком, в свойствах проекта, так и для отдельно взятых файлов с помощью директивы
#nullable enable . Давайте рассмотрим несколько примеров.
Читать →
Советы по оптимизации Unity проекта
Рано или поздно практически любой разработчик на Unity сталкивается с проблемами производительности в своем проекте. И не важно, что это за проект: очередной AAA проект от известной студии, или Match 3 в новом сеттинге от новичков в игровой индустрии. Оптимизировать проект придется так или иначе. Также не важно, под какую платформу (платформы) написан проект: PC, консоль или мобильный. Кажется, что уж в 2019 году-то с гигагерцами не только на компьютерах, но и на телефонах, необходимость в оптимизации для не AAA проектов должна была отпасть. Но нет, приходится экономить спички практически как на заре игростроения. Непонятно, почему так происходит; возможно, это плата за скорость разработки в Unity? Гоу в комментарии, обсудим.
Как нетрудно догадаться из названия статьи, речь сегодня пойдет об оптимизации Unity проектов. Если точнее, то мобильных Unity проектов. Если вам еще только предстоит оптимизировать проект, то, думаю, вы сможете почерпнуть много полезной инофрмации из данной статьи. Если же у вас уже есть опыт в оптмизации и профилировании Unity (да и не только Unity) проектов, вы можете помочь дополнить статью примерами из своего опыта. Нам и остальным читателям это будет очень интересно и полезно.
Искусство оптимизации состоит в том, чтобы за наименьшее количество потраченных сил получить максимальный прирост производительности. Другими словами, не нужно гнаться за оптимизацией каждой функции или алгоритма. Отсюда и первый совет.
Побитовые операции
Сегодня поговорим о побитовых операциях. Думаю, большинство программистов так или иначе сталкивались с побитовыми операциями, или обязательно столкнутся с ними в будущем. Но далеко не все из нас разобрались с ними. И если раньше программирование начиналось чуть ли не со знакомства с побитовыми операциями, то на сегодняший день это далеко не так. Давайте попробуем разобраться, что это за зверь — побитовые операции и с чем его едят, так как в программировании без них никуда. И для начала рассмотрим, где же эти побитовые операции нам могут пригодиться.
Где применяются?
Побитовые операции широко применяются при работе с битовыми полями (флагами) и битовыми масками. Битовые поля позволяют максимально эффективно хранить некоторые состояния, имеющие только два значения: «включен» и «выключен». Access Control List (ACL) — хороший пример битового поля, использующийся для управления доступом к объекту. Например, в Linux и Mac OS каждый файл в системе имеет свой ACL, определяющий полномочия пользователя по чтению, записи или запуску файла. Битовые поля позволяют хранить несколько значений, не расходуя лишнюю память (по одному биту на каждое значение, вместо 4-х или 8-ми). А битовые маски (и побитовые операции), в свою очередь, используются для извлечения необходимых данных из битовых полей.
Довольно трудно обойтись без побитовых операций при реализации сетевой коммуникации. Побитовые операции здесь используются для проверки чек-сумм, определения битов окончания операции, для объеденения команд и данных, сериализации и т.д. и т.п.
Не получится не использовать побитовые операции и при реализации алгоритмов компресии и шифрования. Если взглянуть на любой алгоритм сжатия (например Deflate) или шифрования (например, AES), то мы увидим, что в описании довольно часто всплывают именно биты.
Однозначно существуют области программирования, в которых без побитовых операций просто невозможно обойтись. Сюда можно отнести программирование микроконтроллеров, взаимодействие с реальными устройствами, написание драйверов для них. Также сюда относится реализация программ, эмулирующих реальные устройства, такие,как эмуляторы CD-ROM, игровых приставок или виртуальных компьютеров.
Побитовые операции являются частым гостем в случаях, когда требуется использовать разного рода оптимизации и микрооптимизации кода. Банальный пример: 2 << 4 в большинстве случаев быстрее. чем Math.Pow(2, 5).
Само собой, на этом список не заканчивается, и его можно продолжить, но целью этой статьи не является описание всех возможных сфер применения побитовых операций.
Если вам кажется, что вы не столкнетесь с побитовыми операциями в повседневной работе, т.к. ваша сфера работы не входит в вышеописанные, то у нас для вас «плохие» новости. Встретиться с битовыми операциями можно где угодно, даже там, где, казалось бы, их быть вообще не должно. Но не стоит раньше времени паниковать. Не так страшен черт, как его малюют. Побитовые операции сами по себе довольно просты. И сейчас мы с ними разберемся, а заодно и закроем небольшую брешь в образовании.