Как да получите достъп до RTTI в конструктор на клас?

Този код не е разрешен:

class constructor TOmniMultiPipelineStage.Create;
var
  RTTIType: TRttiType;
begin
  RTTIType:= TRttiContext.GetType(self);
end;

[Грешка dcc32] OtlParallel.pas(5040): E2003 Недеклариран идентификатор: 'self'

Вариантът също не е разрешен:

class constructor TOmniMultiPipelineStage.Create;
var
  RTTIType: TRttiType;
begin
  //Not really what I want because I want the actual type of the class
  //Not a fixed ancestor type 
  RTTIType:= TRttiContext.GetType(TOmniMultiPipelineStage);
end;

[dcc32 грешка] OtlParallel.pas(5039): E2076 Тази форма на извикване на метод е разрешена само за методи на клас или конструктор

Как да получа RTTI информация за клас в неговия конструктор на клас?

Бележка за себе си: преминете през всички наследници на клас: Delphi: По време на изпълнение намирате класове, които произлизат от даден базов клас?


person Johan    schedule 16.07.2014    source източник
comment
възможен дубликат на Delphi use reflection в процедура на клас за получаващ динамичен тип клас   -  person Stefan Glienke    schedule 16.07.2014
comment
методите (и ctors) с префикс клас са членове на класа; те нямат препратка към обекта, така че няма дефинирано „себе“.   -  person David Schwartz    schedule 16.07.2014
comment
@David Не е така. Методите на класа имат Self. Това е мета класът. Статичните членове на класа нямат Аз. Както се случва, конструкторите на класове са статични, въпреки че нямат ключовата дума static.   -  person David Heffernan    schedule 17.07.2014
comment
@david подробности тук: docwiki.embarcadero.com/RADStudio/en/   -  person David Heffernan    schedule 17.07.2014


Отговори (1)


Използвайте метода на класа ClassInfo на TObject:

class constructor TMyClass.ClassCreate;
var
  ctx: TRttiContext;
  typ: TRttiType;
begin
  typ := ctx.GetType(ClassInfo);
end;

Обърнете внимание, че коригирах и синтаксиса на вашето извикване на GetType, което е метод на екземпляр и затова трябва да бъде извикан на екземпляр на TRttiContext.

По-голям проблем за вас е, че конструкторите на класове няма да са ви от полза. Конструкторът на клас е статичен. Те се изпълняват само веднъж, за типа, който ги дефинира. Те не се изпълняват в контекста на производни класове, както очевидно очаквате.

И по същия начин за клас варове, които обсъждате в коментарите. Има само един екземпляр на клас var. Вие очаквате и се надявате, че ще има нови екземпляри за всеки производен клас.

Така че докато ClassInfo отговаря на въпроса, който зададохте, той няма да ви бъде от никаква реална полза.

person David Heffernan    schedule 16.07.2014
comment
Свързан въпрос, ако подкласирам TMyClass, конструкторът на класа за TMyClass също се включва за детето с правилната информация за типа? - person Johan; 16.07.2014
comment
@Johan Конструкторите на клас са статични и затова ще трябва да напишете нов конструктор на клас за всеки подклас. Функцията в моя отговор се изпълнява точно веднъж в живота на модула. - person David Heffernan; 16.07.2014
comment
Хм, това би провалило целта на упражнението. Предполагам, че ще трябва да преместя кода на RTTI заявката в нормален конструктор. Но това би било разточително, защото променливата на класа след това се задава на една и съща стойност отново и отново. - person Johan; 16.07.2014
comment
Бих запитал всички наследници на обекта в този конструктор на клас. - person Johan; 16.07.2014
comment
Можете да изброите всички типове достатъчно лесно и да предприемете действия за всички типове. Споменавате променливи на класа. Ще трябва да декларирате отново променливата на класа във всички производни класове. Има единичен екземпляр на променлива на клас, а не по един за клас. - person David Heffernan; 16.07.2014
comment
@Johan Имате ли нужда от повече помощ тук? - person David Heffernan; 18.07.2014
comment
Благодаря, Дейвид, не, готин съм. Преместих кода за отражение в обикновен стар конструктор. Това е малко разточително, но конструкторите не се изпълняват в тесен цикъл (само веднъж на всеки няколко секунди), така че е ОК. - person Johan; 18.07.2014