Может ли RTTI запрашивать типы из кода проекта во время разработки?

Я хотел бы использовать RTTI для проверки типов, содержащихся в исходных файлах проекта, во время разработки, а не во время выполнения.

Насколько мне известно, это не поддерживается, но обсуждение в комментариях этот вопрос указывает, что это возможно и было для нескольких версий Delphi. Это первый раз, когда я слышу об этой функции, и пока я не смог воспроизвести ее для себя.

Вот мой тестовый пример. Он использует простой TListBox потомок TMyListBox, который имеет string свойство TypeToExplore, которое при установке заполняет окно списка свойствами введенного в него полного имени типа.

unit MyListBox;

interface

uses
  SysUtils, Classes, Controls, StdCtrls;

type
  TMyListBox = class(TListBox)
  private
    FTypeToExplore : string;
    procedure SetTypeToExplore(const inValue: string);
    procedure FillWithTypeDetails;
  published
    property TypeToExplore : string read FTypeToExplore write SetTypeToExplore;
  end;

procedure Register;

implementation

uses
  RTTI, TypInfo;

procedure TMyListBox.SetTypeToExplore(const inValue: string);
begin
  if inValue = FTypeToExplore then
    Exit;

  FTypeToExplore := inValue;
  Clear;
  FillWithTypeDetails;
end;

procedure TMyListBox.FillWithTypeDetails;
var
  context : TRTTIContext;
  theType : TRttiType;
  properties : TArray<TRttiProperty>;
  prop : TRttiProperty;
begin
  theType := context.FindType(FTypeToExplore);
  if Assigned(theType) then begin
    properties := theType.GetProperties;
    for prop in properties do
      Items.Add(prop.Name);
  end else
    Items.Add('No type found');
end;

procedure Register;
begin
  RegisterComponents('Samples', [TMyListBox]);
end;

end.

Используя этот TMyListBox компонент I

  • Скомпилируйте и установите его в Delphi XE IDE.
  • Добавьте расположение DCU компонента в путь к библиотеке IDE.
  • Перезапустите IDE, чтобы убедиться
  • Создайте новый пустой Project1
  • Бросьте MyListBox1 на TForm1
  • Сохраните, скомпилируйте и запустите Project1
  • Закройте приложение Project1 (но не проект)
  • В инспекторе объектов установите MyListBox1.TypeToExplore на Unit1.TForm1

И MyListBox1 сообщает «Тип не найден», что согласуется с моим пониманием того, как работает RTTI, то есть во время разработки он может исследовать только типы, которые содержатся в пакетах, установленных в IDE, а не в исходных файлах проекта.

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


person LachlanG    schedule 29.01.2012    source источник
comment
+1 Хороший вопрос. Я очень заинтригован, чтобы узнать, что ответ!!   -  person David Heffernan    schedule 30.01.2012
comment
Вы хотите, чтобы функциональность заполнения TListBox всеми свойствами полного имени типа была доступна как во время разработки, так и во время выполнения?   -  person menjaraz    schedule 30.01.2012
comment
@menjaraz: Да, как во время разработки, так и во время выполнения. Этот пример отлично работает во время выполнения с полным именем типа Unit1.TForm1, но не во время разработки.   -  person LachlanG    schedule 30.01.2012
comment
Тихо тут не так.....   -  person David Heffernan    schedule 30.01.2012
comment
Кроме того, в вашем коде, безусловно, есть ошибка ... поскольку он возвращает тип не найден, даже если вы предоставляете имя типа для класса, содержащегося в пакете! Вы никогда не звоните context := TRttiContext.Create или context.Free!   -  person LaKraven    schedule 30.01.2012
comment
@LaKraven На самом деле вам не нужно звонить ни одному из этих   -  person David Heffernan    schedule 31.01.2012
comment
@DavidHeffernan интересно ... о чем я не знал! Выяснил, почему он ничего не возвращает для типов, привязанных к пакету: они чувствительны к регистру (что действительно имеет смысл).   -  person LaKraven    schedule 31.01.2012


Ответы (2)


Прочитав исходный код RTTI.pas, я пришел к выводу, что Delphi RTTI не может проверять текущий проект IDE. Во время разработки RTTI может проверять типы внутри пакетов, размещенных в среде IDE. Он не может проверять дальше этого.

person David Heffernan    schedule 30.01.2012
comment
Теперь, еще раз взглянув на первоисточник моего Wrapper Unit Generator (первоначально написанный для D2010 еще в конце 2009 года), я могу подтвердить то, что Дэвид говорит здесь! Мой Wrapper Unit Generator на самом деле создает пакет с теми же свойствами, что и выбранный проект, регистрируя его в среде IDE... ТОГДА он использует RTTI! Теперь я чувствую себя и растерянным, и немного глупым! - person LaKraven; 31.01.2012
comment
@LaKraven Ну, я рад, что мы все это прояснили. Я вернул ваши правки к моему ответу на другой вопрос. Ваше принятие другого ответа, возможно, немного сбивает с толку. - person David Heffernan; 31.01.2012
comment
Я очень удивлен тем, как много я забыл о своем методе с тех пор, как написал исходный код всего два года назад! - person LaKraven; 31.01.2012
comment
О, это позор. Я с нетерпением ждал возможности использовать эту секретную возможность RTTI. Спасибо вам обоим, это была интересная дискуссия и эксперимент в любом случае. - person LachlanG; 31.01.2012

Вопрос. Можно ли запрашивать/использовать типы в Delphi IDE во время разработки?

О: Да, конечно :)

Вопрос. Использует ли IDE напрямую RTTI?

Насколько мне известно, «знание» IDE о типах, методах и т. д. является отдельным и отличным от RTTI во время выполнения. Насколько я знаю, это в равной степени верно, например, для интроспекции Java/среды разработки Eclipse/отладчика или .Net Reflection/среды разработки MSVS/отладчика.

Эта статья может помочь:

person paulsm4    schedule 29.01.2012
comment
@paulsm4 Статья, на которую вы ссылаетесь, предшествует расширенному RTTI (D2010). Это не кажется актуальным для этого вопроса, который касается расширенного RTTI. - person David Heffernan; 30.01.2012
comment
Если вы говорите, что если оно старое, то оно должно быть неправильным — это чепуха. Если вы говорите, что правила могли измениться, когда был введен Enhanced RTTI, это более правдоподобно. Но я так не думаю. Я сказал выше - и я все еще верю - даже для последней / самой лучшей XE2 - что RTTI - это вещь времени выполнения, более или менее независимая от IDE (и отладчика). Вот еще доказательства, подтверждающие это мнение: delphi.about.com/b/2011/07/26/ PS: статья остается очень и очень хорошей. ПО МОЕМУ МНЕНИЮ... - person paulsm4; 30.01.2012
comment
ЛаКрэйвен утверждал, что расширенный RTTI может анализировать активный проект во время разработки. Поэтому я думаю, что этот вопрос касается расширенного RTTI. - person David Heffernan; 30.01.2012