Как создать объект-экземпляр с RTTI в Delphi 2010?

Как все мы известные, когда мы вызываем конструктора класса как это:

instance := TSomeClass.Create;

Компилятор Delphi на самом деле делает следующие вещи:

  1. Назовите статический метод NewInstance, чтобы выделить память и инициализировать расположение памяти.
  2. Назовите метод конструктора выполнить инициализацию класса
  3. Назовите метод AfterConstruction

Это просто и легко для понимания. но я не очень уверен, как компилятор обрабатывает исключения во втором и третьем шаге.

Кажется, что нет никакого явного способа создать экземпляр с помощью метода конструктора RTTI в D2010. таким образом, я записал простую функцию в Платформе Spring для Delphi для репродуцирования процесса создания.

class function TActivator.CreateInstance(instanceType: TRttiInstanceType;
  constructorMethod: TRttiMethod; const arguments: array of TValue): TObject;
var
  classType: TClass;
begin
  TArgument.CheckNotNull(instanceType, 'instanceType');
  TArgument.CheckNotNull(constructorMethod, 'constructorMethod');
  classType := instanceType.MetaclassType;
  Result := classType.NewInstance;
  try
    constructorMethod.Invoke(Result, arguments);
  except
    on Exception do
    begin
      if Result is TInterfacedObject then
      begin
        Dec(TInterfacedObjectHack(Result).FRefCount);
      end;
      Result.Free;
      raise;
    end;
  end;
  try
    Result.AfterConstruction;
  except
    on Exception do
    begin
      Result.Free;
      raise;
    end;
  end;
end;

Я чувствую это, возможно, не 100%-е право. поэтому покажите мне путь.Спасибо!

14
задан Sertac Akyuz 8 July 2010 в 12:40
поделиться

1 ответ

Вызов конструктора и передача класса в качестве аргумента Self (в отличие от экземпляра) правильно построит класс. Процесс построения включает в себя NewInstance , AfterConstruction и т. Д., Которые вы выполняете здесь вручную: в этом нет необходимости.

Этого должно быть достаточно:

Result := constructorMethod.Invoke(instanceType.MetaclassType, arguments);

Странность Delphi заключается в том, как он позволяет вызывать конструкторы как для экземпляров, так и для классов. Эта функция используется как своего рода «новое размещение» (в терминологии C ++) для создания формы, так что глобальная переменная формы (например, Form1 по умолчанию для первой формы) назначается в то время, когда Вызывается конструктор OnCreate . Таким образом, ваш код не вызывает исключения. Но более нормально передавать в качестве аргумента Self класс, а не экземпляр.

18
ответ дан 1 December 2019 в 13:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: