Вы можете объявлять метаклассы, но не можете определять их с точки зрения того, какие интерфейсы реализует базовый класс. Реализация интерфейса может быть проверена только во время выполнения.
Вы можете передать свою Dummy
функцию метаклассу, но вы не можете использовать этот метакласс для приведения типа вашего простого указателя к более конкретному типу. Приведение типов является операцией времени компиляции, но фактическое значение параметра метакласса неизвестно до времени выполнения. Лучшее, что вы можете сделать, это привести его к базовому классу метакласса. Затем вы можете вызвать все методы, которые определены в этом базовом классе.
Но, похоже, вам на самом деле все равно, что такое базовый класс, если класс реализует ваш интерфейс. В этом случае вы можете игнорировать параметр метакласса. Введите тип вашего указателя как TObject
(или, еще лучше, объявите gHardCodedPointer
до be a TObject
в первую очередь), а затем используйте функцию Supports
, чтобы получить ссылка на интерфейс.
var
SupportsInterface: Boolean;
Some: ISomeInterface;
begin
SupportsInterface := Supports(TObject(gHardCodedPointer), ISomeInterface, Some);
Assert(SupportsInterface, 'Programmer stored bad class instance in gHardCodedPointer');
Some.SomeMethod;
end;
Если вы действительно заботитесь о параметре метакласса, вы также можете добавить к нему некоторое принудительное применение. Вы можете проверить, реализует ли данный класс ваш интерфейс, и проверить, является ли объект в gHardCodedPointer
экземпляром этого класса:
Assert(ASomeClassToWorkWith.GetInterfaceEntry(ISomeInterface) <> nil);
Assert(TObject(gHardCodedPointer).InheritsFrom(ASomeClassToWorkWith));
Но обратите внимание, что вам не нужно проверять ни один из этих результатов, чтобы иметь возможность звонить SomeMethod
на gHardCodedPointer
. Они на самом деле не имеют значения.
Кстати, единственное жестко закодированное значение указателя, которое вы можете надеяться получить в Delphi, это nil
. Все остальные значения указателя являются адресами, которые очень трудно предсказать во время компиляции, потому что компилятор, компоновщик и загрузчик все определяют, где все в действительности идет в памяти. Я предлагаю вам придумать какое-то другое имя для этой переменной, которое более точно описывает, что она на самом деле содержит.