DelphiWin32 - 生成特定类的对象

时间:2010-11-22 14:32:51

标签: delphi delphi-2009

我正在使用Delphi 2009.我有一个带有几个项目的TListBox。我想为所选的每个项目生成特定类的对象。因此,如果用户选择项目编号2并单击“创建”按钮,则会创建特定类的对象。我正在考虑实现它只是检查当前项目的索引值,然后使用if-then-else。或者我应该使用类引用,即每次单击项目我设置类引用的类型然后我在按钮的OnClick事件中创建对象?我想避免所有这些控件,只是根据item string的值创建对象。任何的想法?非常感谢!

2 个答案:

答案 0 :(得分:4)

有几种选择。

简单索引

简单的解决方案是:

case ListBox1.ItemIndex of
  0 : temp := TApple.Create;
  1 : temp := TPineapple.Create;
  2 : temp := TGrape.Create;
else
  raise EFruitError.Create('Unknown fruit');
end;

很清楚,但你必须在两个地方维护清单,这可能会导致错误。

类引用

假设所有水果都是用TFruit从虚拟构造器下降的。然后你可以这样做:

procedure TForm1.FormCreate(const Sender: TObject);
begin
  ListBox1.AddObject('Apple', TApple);
  ListBox1.AddObject('Pineapple', TPineapple);
  ListBox1.AddObject('Grape', TGrape);
end;

// Event handler:
procedure TForm1.CreateButtonClick(const Sender: TObject);
begin
  if ListBox1.ItemIndex>=0 then
    temp := TFruit(ListBox1.Items.Objects[ListBox1.ItemIndex]).Create;
end;

这有一个维护点。哪个好。

基于名称的参考 但是,如果要根据列表中的名称创建对象,可以创建某种工厂:

type
  TFruitClass = class of TFruit;
  TFruitFactory = class
  public
    class function CreateFruit(const AName: string): TFruit;
    class procedure RegisterFruit(const AName: string; const AFruitClass: TFruitClass);
  end;

工厂用于将类绑定到名称。每个类都使用名称注册。现在,您只需将名称提供给工厂,工厂将返回所需的类。

答案 1 :(得分:3)

要添加到Gamecat的答案,您可以在'classes.pas'中使用类实用程序功能。下面的示例使用GetClass函数(并假设要从TControl继续创建对象):

procedure TForm1.FormCreate(Sender: TObject);
begin
  ListBox1.Items.CommaText := 'TEdit,TButton,TPanel';
  RegisterClasses([TButton, TEdit, TPanel]);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  pc: TPersistentClass;
  c: TControl;
begin
  if ListBox1.ItemIndex > -1 then begin
    pc := GetClass(ListBox1.Items[ListBox1.ItemIndex]);
    if Assigned(pc) then begin
      c := TControlClass(pc).Create(Self);
      c.Parent := Self;
    end;
  end;
end;