Игорь Моисеев @kayan
Технический директор, специалист широкого профиля
Information
- Rating
- Does not participate
- Location
- Иннополис, Татарстан, Россия
- Date of birth
- Registered
- Activity
Specialization
Fullstack Developer, Chief Technology Officer (CTO)
Lead
C#
.NET Core
Не нашли бы. Если дело не является особо важным и публичным, конечно. За контрафакт организацию (в нашей области, по крайней мере) засудить очень тяжело, если они сами не наделают глупостей.
В ситуации с госучреждениями, более того, я считаю, что действительно проблемы в основном идут не от установок начальства и от распилов, а от безалберности работников. Ставят сами Word, например, сами ставят (как в Роскомнадзоре, все скорее) Photoshop. Просто им лично так удобнее или подкалымить на работе надо. Государство можно осудить за то, в основном, что оно недостаточно сильно следит за «перевоспитанием», тут согласен в целом с автором.
Вы меня упорно пытаетесь убедить в том, что я не утверждаю, а именно в том, что подход к изменямости решает все проблемы.
Нет, она решает определенное количество неявных и известных проблем за счет явных и недвусмысленных объявлений, поэтому вероятность случайной и непредсказуемой без знания всего кода ошибки снижается.
Касаемо примера — он, конечно, весьма химерический, но он пример вреда обычной измеямой структуры, но я говорил о неизменяемости хэш-кода ключа, а не о изменямости структуры.
И хэш определить и неизменяемой сделать.
Хэш могут потом и поменять, включив по ошибке потенциально изменяемое поле.
Вопрос не в том, зачем изменять структуру (хотя и в этом случае сразу вопрос — а почему не класс?), а зачем передавать изменяемую структуру как ключ.
Либо делать для удобного редактирования класс, а для привязки его к таблице — неизменяемый структурный ключ этого отрезка.
Например, предоставляющей исходный массив этих ключей (не спрашивайте зачем, случае разные бывают).
Я не очень понял, зачем эти варианты. Речь идет о минимализации возможностей прострелить себе ногу. С точки зрения .NET ситуация со структурами, ссылающимися на классы, а тем более реализация своего хэш-кода для класса — вполне возможные вещи.
И чтобы другие разработчики, не знакомые с тонкостями реализации и не знающие, что «нельзя переопределять у этого класса хэш-код, а то в другом месте коллекция упадет», не стреляли по ногам, предлагается политика, позволяющая обезопаситься в этом и других случаях.
Легко ответить на вопросы, зачем переопределять хэш-код и зачем передавать структуру как ключ, но на вопрос зачем передавать как ключ изменяемую структуру — гораздо сложнее.
Мы инициализируем у структуры Key поле RefField и отдаем эту структуру в качестве ключа. Несмотря на то, что в стандартных реализациях коллекций мы не сможем достучаться до непосредственно значения ключа типа Key (всегда будем получать копию), поменять значение поля Field у известного нам объекта типа Reference мы можем. Соответственно, сохраненный нами в коллекции ключ будет иметь не тот хэш-код, что при занесении в коллекцию, что приведет к невозможности корректного поиска этого ключа.
И это именно та ситуация, где поле типа Reference должно быть либо immutable (readonly не спасет), либо value-type.
В нашем случае спасает, например, если поменять поля в структуре Key местами. Попробуйте.
Но комментарий разработчиков (и сам автор), как мне кажется, описывает именно общую возможную ситуацию с хэш-кодом структуры.
Хотя ситуация с изменением объекта после его помещения в хэш таблицу сама по себе не очень хорошая.
И это, вместе с остальным, является аргументом, почему структуры, которые чаще всего используют как ключи, надо стараться делать неизменяемыми. Об этом «остальном» можно почитать тут: stackoverflow.com/questions/441309/why-are-mutable-structs-evil. Ну и у Липперта в блоге.
Более того, даже подобный вызов у меня в 1 случае из 100, наверное, не помогает.
Наоборот, как несложно догадаться, быть не может. Точнее, атрибуты-то можно написать, но область видимости все равно будет от самого глобального объекта.
Грубо говоря, чем больше у ножика лезвий, тем тяжелее найти нужное. Но это мы уже вообще в глубокую философию ушли. :)
По теме же советую посмотреть на возможности MEF 2 (работа с обобщениями, RegistrationBuilder, дочерние контейнеры). Разумеется, он по-прежнему аскетичен, по сравнению с тем же автофаком например, но, как мне кажется, в 80% приложений его хватит за глаза.
В каких-то ситуациях будет разумно вообще контейнер не использовать.
Опасность опять же шаблонов в том, что, увлекшись кодом, можно забыть о том, что за ним находится.
Причем здесь MEF? :) Он и есть полнофункциональное средство в своей области без всякого лишнего.
Да будет, когда неясно, когда и кому объект ликвидировать.
Ну вот совершенно не согласен. Я считаю, что смешение в контейнере объектов сервисной категории и объектов, представляющих данные, крайне неполезно. Т.е. не очень хорошо хранить в контейнере соединения с базой, а вот класс, предоставляющий соединения, который композиционно всякое использует — нормально. С таким подходом у меня ограничений даже с мефом не возникало.
Самое страшное в AOP в неумелых руках (я не имею в виду вас) — совершенно неочевидные и, подчас, конфликтные инъекции. Собственно, неконтролируемое смешивание всего и вся, как мне кажется, и есть самое серьезное ограничение подобного подхода — ну типа как множественное наследование, только еще менее очевидное. Продуманная архитектура, практически устраняет необходимость в широком применении AOP. А сделать инъекцию со своим временем жизни вполне возможно, ну это уже в статью пойдет. Обвешивать проксями и прочим без сложностей тоже можно, при условии, что написанный пользователем класс позволяет подобные паттерны, и это смотрится вполне естественно в MEF…
Совершенно необязательно. Есть класс RegistrationBuilder.
Многия знания, как говорится, рождают многия печали. :) Обилие возможностей приводит к каше на проекте, когда сложно разобраться, какой объект как получается и что из себя представляет (это, конечно, на больших проектах и в команде чувствуется).
Плюсы мефа я уже указал — простой в использовании, наглядный и надежный вроде как фреймворк для сбора композиции. Зачем пилить полено лазером, если можно пилой?