Я изучаю Цейлон и у меня есть вопросы по поводу его метамодели. Я хочу создать некоторый базовый класс «DataContainer», который позволяет создавать экземпляры неизменяемых классов со встроенной реализацией equals-hash: например. Идентификатор (125, "ab") == Идентификатор (125, "ab") Таким образом, базовый класс должен собирать все общие непеременные значения и использовать эту информацию в методах "хэш" и "равно". Я написал этот код:
shared abstract class DataContainer(ClassDeclaration declaration) {
value members = {
for (i in declaration.memberDeclarations<ValueDeclaration>())
if (!i.variable, i.name != "hash", i.name != "string") i
};
variable Integer? hashCode = null;
shared actual Boolean equals(Object that) {
if (is DataContainer that) {
for (item in members) {
value thisMember = item.memberGet(this);
value thatMember = item.memberGet(that);
if (exists thisMember, exists thatMember) {
if (thisMember != thatMember) { return false; }
} else if (thisMember exists != thatMember exists) { return false; }
}
return true;
}
return false;
}
shared actual Integer hash => hashCode else (hashCode = calculateHash());
Integer calculateHash() {
variable value result = 0;
for(i in members) {
if (exists member = i.memberGet(this)) {
result = result.xor(member.hash);
}
}
return result;
}
}
class Identifier(shared Integer? id, shared String? name) extends DataContainer(`class`) {}
Класс Identifier является клиентом DataContainer. Мне нравится это решение в целом, но я должен передать «класс» в конструктор суперкласса, потому что, если я использую «класс» внутри DataContainer, он не видит никаких членов подкласса. Как я могу получить фактический список членов расширенного класса в методах базового класса? Что-то вроде "это" не работает...