Delphi 2010: что случилось с TRTTIConstructor? - PullRequest
8 голосов
/ 23 марта 2010

У меня есть два вопроса (из них хотя бы один касается RTTI в D2010 и динамического создания экземпляров)

  1. Я читал то, что кажется фольгой для конференции на конференции Барри Келли, и нашел на с. 13 то, что выглядело действительно интересно: TRTTIConstructor.Invoke. В соседнем пуле находится «Динамическое конструирование экземпляров без использования виртуальных конструкторов и метаклассов». Это похоже на отличную функцию (и именно то, что мне нужно, кстати)! Однако, когда я просматриваю документы D2010 (ms-help: //embarcadero.rs2010/vcl/Rtti.html), я не могу найти его. Это было отозвано?
  2. Каков минимальный способ создания экземпляра класса, если имя класса хранится в строке?

Ответы [ 2 ]

10 голосов
/ 23 марта 2010

Я думаю, что функциональность была поглощена TRttiMethod. Он имеет свойства IsConstructor, IsDestructor и IsClassMethod, так что его можно использовать как для «специальных» методов, так и для обычных.

Что касается вопроса 2, попробуйте что-то вроде этого:

function GetConstructor(val: TRttiInstanceType): TRttiMethod;
var
   method: TRttiMethod;
begin
   for method in val.GetMethods('Create') do
   begin
      if (method.IsConstructor) and (length(method.GetParameters) = 0) then
         exit(method);
   end;
   raise EInsufficientRTTI.CreateFmt('No simple constructor available for class %s ',
                                     [val.MetaclassType.ClassName]);
end;

Находит самый высокий конструктор с именем Create, который не принимает параметров. Вы можете изменить его, чтобы искать другие конструкторы с другими сигнатурами, если вы знаете, что ищете. Затем просто позвоните Invoke, чтобы получить результат.

2 голосов
/ 24 марта 2010

Хотя вы можете вызвать .GetMethod (), чтобы получить конструктор, вы также можете сделать следующее, чтобы создать экземпляры объектов без параметров для конструктора.

function CreateInstance(aType : TRttiType) : TObject;
begin
  // Option #1
  result := aType.AsInstance.MetaclassType.Create;
  // Option #2
  result := aType.GetMethod('Create').Invoke(aType.AsInstance.MetaclassType,[]);
end;

Если вы знаете базовый тип, вы можете набрать класс для передачи параметров, если хотите. Вот пример создания компонента

result := TComponentClass(aType.AsInstance.MetaClassType).Create(OwnerValue);

...