Язык D обладает богатыми возможностями кодогенерации, которые позволяют упростить процесс добавления своих свойств в структуру и класс.
А что если потребуется в класс добавить свойство, которое будет выдавать значение того типа, который нужен в данный момент?
Осуществить подобную «махинацию» можно с помощью следующего шаблона:
template addTypedGetter(string propertyVariableName, string propertyName) { import std.string : format; const char[] addTypedGetter = format( ` @property { T %2$s(T)() const { alias typeof(return) returnType; return cast(returnType) %1$s; } }`, propertyVariableName, propertyName ); }
Шаблон addTypedGetter предполагает наличие некоторой внутренней переменной, в которой и храниться значение интересующего нас свойства. addTypedGetter принимает два аргумента: propertyVariableName — имя внутренней переменной со значением свойства и propertyName — имя геттера (т.е. имя процедуры, с помощью которой будет производиться получение значения свойства).
Чтобы применить шаблон нужно просто его «подмешать» в определение нужного класса, добавив внутрь класса подобие следующего:
// красная компонента цвета mixin(addTypedGetter!("R", "red"));
Эта строка добавит свойство red в класс, а получить значение нужного типа можно так:
<переменная класса>.red!float;
то есть, просто указав нужный тип после восклицательного знака.
Естественно, у addTypedGetter есть ограничения: данный шаблон работает только со встроенными типами или такими, у которых определен метод opCast, учитывающий преобразование типа данных, определенного пользователем, в нужный тип.
Но даже несмотря на такое жесткое ограничение, приведенный шаблон является очень мощным инструментом и может служить основой для создания более гибких и универсальных шаблонов.