Search
Write a publication
Pull to refresh

Comments 7

Какая конечная цель всего этого?

Представим, что перед нами стоит задача описать объект, не позволяющий себя изменять, а его конструирование не является тривиальным.

Это же просто иммутабельный объект с приватным конструктором. Зачем всё усложнять?

Цель - перенести иммутабельтность из характеристики типа в его возможности, то есть аргумент типа будет определять - иммутабелен объект или нет.

Однако, иммутабельность - это только пример. Далее этот принцип расширяется до описания вообще любого поведения объекта.

Суть квалификаторов в том, что для описания различных ограниченных сценариев взаимодействия достаточно задекларировать только одну сущность, а компилятор не даст произвести недопустимых операций над объектом.

Из этого следует, что для некоторых объектов без поведения, например к классическим DTO, данный подход применять особого смысла нет.

Дак компилятор и так не дает произвести недоступные операции над объектом. Если вам нужен контекстный доступ к объекту в зависимости от квалификатора, типа const в с++ то это не реализуемо как и в C++ так и в C#, объект протечет из контекста и будет изменён человеком или либой которая не в курсе ваших договоренностей. Все это тщетно без гарантий компилятора и рантайма.

И если уж и делать такое то можно было сделать проще, через генерацию интерфейса с нужными методами и пропертями согласно квалификатора на них. Типа если нужен const интерфейс на класс находишь все методы на которые повесили [Const()] атрибут и генеришь IConstMyClass интерфейс.

Компилятор это гарантирует на уровне текущей информации о типе в контексте использования.

Рантайм - действительно, не гарантирует.

Однако, при использовании объекта вызвается не определённый разработчиком метод, а сгенерированная прослойка, выполняющая предварительные проверки на соответствие квалификации.

Методы, определяемые разработчиком, должны быть помечены private или protected (требование кодогенератора, он даже предупреждение выдаёт и отказывает в генерации кода), и не могут быть вызваны без использования рефлексии. Это и гарантирует наличие проверок.

И если уж и делать такое то можно было сделать проще, через генерацию интерфейса с нужными методами и пропертями согласно квалификатора на них. Типа если нужен const интерфейс на класс находишь все методы на которые повесили [Const()] атрибут и генеришь IConstMyClass интерфейс.

Внезапно, в статье именно это и описано.

Только результат без "шелухи" в виде множества однотипных интерфейсов с префиксом в названии.

Принцип прост: что описали - с тем и работаем; не нужно наследоваться, реализовывать методы, редактировать тонну кода при смене имени типа (с учётом возможностей IDE по автопереименованию).

Да, но вариант с интерфейсом может ещё со скрипом пройти код ревью, а вот механизм с рефлексией, кодогенерацией и объяснением на 10 страниц А4 нет. Если статья описывает чисто академический эксперимент, то интересно, если реальный проект, то это нежизнеспособно.

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

Это концепт, во всех смыслах, однако его можно попробовать здесь и сейчас. Тянуть концепт в прод - очевидно плохая идея, я прямо против этого. Но проектом он от этого быть не перестаёт.

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

Да, но вариант с интерфейсом может ещё со скрипом пройти код ревью, а вот механизм с рефлексией, кодогенерацией и объяснением на 10 страниц А4 нет.

Так можно вообще внешними зависимостями не пользоваться. EF Core, различные мапперы, WCF, Apizr/Refit и прочее и прочее - содержит всё вышеперечисленное, только объясняется сильно больше чем на 10 страницах.

Sign up to leave a comment.

Articles