Есть ли способ создать экземпляр класса по его имени в Delphi?

Я хотел бы создать экземпляр класса, но у меня есть только его имя в строке. Есть ли способ?


person Ricardo Acras    schedule 31.03.2009    source источник


Ответы (2)


Это из справки Delphi (Delphi 2006, но также доступно по крайней мере из Delphi 7):

Синтаксис function GetClass(const AClassName: string): TPersistentClass;

Описание Вызовите GetClass, чтобы получить класс по имени класса. Этот класс можно использовать в качестве параметра для подпрограмм, которым требуется класс. Класс должен быть зарегистрирован, прежде чем GetClass сможет его найти. Классы форм и классы компонентов, на которые есть ссылки в объявлении формы (переменные экземпляра), автоматически регистрируются при загрузке формы. Другие классы можно зарегистрировать, вызвав RegisterClass или RegisterClasses.

Вот пример кода. Работает как таковой только потому, что TButton является TControl и, следовательно, приведение типа допустимо.

procedure TForm1.FormCreate(Sender: TObject);
begin
  RegisterClasses([TButton, TForm]);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  CRef : TPersistentClass;
  AControl : TControl;
begin
  CRef := GetClass('TButton');
  if CRef<>nil then
  begin
     AControl := TControl(TControlClass(CRef).Create(Self));
     with AControl do
     begin
        Parent := Self;
        Width := 50;
        Height := 30;
     end;
  end;
end;
person Ralph M. Rickenbach    schedule 31.03.2009
comment
Отличное решение. Но теперь я столкнулся с другой проблемой. Класс, который я хотел бы создать, — это мой собственный класс, реализующий интерфейс. И registerClass должен вызываться с постоянным классом. Любая идея? - person Ricardo Acras; 31.03.2009
comment
Можно ли вывести ваш класс или одного из его предков из TPersistent? - person Ralph M. Rickenbach; 31.03.2009
comment
Я так не думаю, поскольку он реализует интерфейс и должен быть производным от TInterfaceObject. - person Ricardo Acras; 31.03.2009
comment
Я нашел TInterfacedPersistent, просто отлично. Спасибо. - person Ricardo Acras; 31.03.2009
comment
Не обращайте внимания на мое предыдущее предложение. TInterfacedPersistent — это то, что вам нужно. Я думал, что он существует, но не мог вспомнить название. - person Jim McKeeth; 31.03.2009
comment
Вам не нужно использовать механизм RegisterClass VCL, если вы не хотите менять иерархию классов — напишите свой собственный. Просто взгляните на TRegGroup.GetClass, TRegGroup.RegisterClass и т. д. в Classes.pas. Вы можете упростить код, выбросив слой RegGroups. - person Uli Gerhardt; 31.03.2009

Когда мне нужно было это сделать, я построил свою собственную фабрику объектов, которая использует специально созданный подкласс TStringList, в настоящее время я использую Delphi 7, поэтому класс списка строк поддерживает только присоединение объекта к строке, затем я получил подкласс TStringList, чтобы сделать это возможно также обрабатывать типы классов, поэтому теперь я могу создать экземпляр объекта, просто передав его имя класса фабрике. Работает так:

1 – загрузить фабрику одноэлементных объектов;
2 – зарегистрировать любой объект в фабрике, это может быть в разделе инициализации модуля;

Основными методами Фабрики могут быть: isClassRegistered, registerClass, instanceiateClass(ClassName: STring): TObject;

Таким образом, я могу создать экземпляр любого объекта или использовать предыдущий созданный объект или даже их подмножество.

Я предпочитаю использовать перечисляемый тип вместо строки для идентификации класса.

Замечания: Это очень-очень лаконичный пример, полностью функциональный код сложнее, но, поверьте, не слишком.

person Gedean Dias    schedule 22.06.2009