Как определить тип реализующего объекта интерфейса
Я пытаюсь написать модульный тест для простого фабричного класса, который создает один из нескольких возможных реализующих объектов и возвращает его в качестве ссылки на интерфейс.
DUnit имеет встроенную процедуру, CheckIs(AObject: TObject; AClass: TClass; msg: string)
то, что на основе его имени и параметров, которые он принимает, должно пройти проверку, если тип класса объекта не соответствует ожидаемому. Единственная проблема заключается в том, что требуется ссылка на объект, а не ссылка на интерфейс.
Поэтому я пытаюсь использовать CheckTrue
и выполнить сравнение в теле теста, но я не так знаком с поддержкой проверки типов в Delphi, как я с C#.
Я знаю is
об операторе не может быть и речи, поскольку он работает только со ссылками на объекты.
CheckTrue(LMyInterfaceReference {comparison here} TMyClass);
Какие-либо предложения?
Кстати, я использую Delphi 2009, поэтому у меня нет доступа к новой поддержке RTTI, добавленной в 2010+.
3 ответа
Если вам не нравятся хаки и вы не хотите переходить на Delphi 2010+, вы можете использовать такой интерфейс:
IImplementingObjectInterface = interface
function GetImplementingObject: TObject;
end;
Убедитесь, что ваши объекты также реализуют этот интерфейс и используют его для извлечения объекта реализации. Если вам нужно сделать это для множества объектов, вы можете определить свои собственные TInterfacedObject
производный, который уже реализует это, так что вы можете просто изменить свое наследование и все готово.
Мне интересно, почему вы ДОЛЖНЫ проверить это... может быть, вам и не нужно.
Но если знание базового объекта интерфейса является обязательным, у вас есть два варианта:
- Добавьте метод к интерфейсу, который возвращает базовый объект, просто TObject, и реализуйте это в каждом классе, просто возвращая self.
- Взломайте немного, например, используя этот интерфейс для рутинной работы объекта.
Barry Kelly ( Barry Kelly (один из главных инженеров Embarcadero Delphi Compiler) на этой неделе написал прекрасную уродливую альтернативу интерфейсу для приведения объектов.
Это отвечает на ваш вопрос.
Самое интересное, что Хальвард Вассботн написал очень похожий кусок кода еще в 2004 году.
Начиная с Delphi 2010, вы можете просто использовать is
проверить или as
приведение для возврата от ссылок на интерфейсы к ссылкам на объекты.
--jeroen