如何识别对象类型?

时间:2011-12-06 16:08:18

标签: delphi oop pointers

假设我有一个Treeview,它包含带有Object指针的项目。如何从所选项目中确定对象是什么,以便我可以访问它?

以下是一些提供想法的类和代码的基本示例: 注意:TChildObject1和TChildObject2继承自TMyObject。

type
  TMyObject = class
  private
    FName: string;
  public
    property Name: string read FName write FName;

    constructor Create(aName: string);
  end;

type
  TChildObject1 = class(TMyObject)
  private
    FSomeString: string;
  public
    property SomeString: string read FSomeString write FSomeString;

    constructor Create(aName: string);
    destructor Destroy; override;
  end;

type
  TChildObject2 = class(TMyObject)
  private
    FSomeInteger: integer;
  public
    property SomeInteger: integer read FSomeInteger write FSomeInteger;

    constructor Create(aName: string);
    destructor Destroy; override;
  end;

让我们说它们已经创建并添加到TTreeview中,如下所示:

procedure NewChild1(aTreeView: TTreeView; aName: string);
var
  Obj: TChildObject1;
begin
  Obj := TChildObject1.Create(aName);
  try
    aTreeView.Items.AddObject(nil, Obj.Name, Obj);
  finally
    Obj.Free;
  end;
end;

procedure NewChild2(aTreeView: TTreeView; aName: string);
var
  Obj: TChildObject2;
begin
  Obj := TChildObject2.Create(aName);
  try
    aTreeView.Items.AddObject(nil, Obj.Name, Obj);
  finally
    Obj.Free;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  // add the items to the tree
  NewChild1(TreeView1, 'Child Object 1');
  NewChild2(TreeView1, 'Child Object 2');
end;

现在,当我在Treeview中选择一个Node时,如何确定指针指向哪个Object类?我尝试了这个,这是行不通的:

注意:这不是错误,但它没有返回正确的值(即,没有拾取正确的对象)

procedure TForm1.TreeView1Click(Sender: TObject);
var
  Obj: TMyObject;
begin
  if TreeView1.Selected <> nil then
  begin
    Obj := TMyObject(TreeView1.Selected.Data);

    if Obj is TChildObject1 then
    begin
      Edit1.Text := 'this node is a child1 object';
    end else
    if Obj is TChildObject2 then
    begin
      Edit1.Text := 'and this node is child 2 object';
    end;
  end;
end;

我可以像下面这样做,但我认为不是正确的方法,它意味着大量的检查,声明,分配等。

procedure TForm1.TreeView1Click(Sender: TObject);
var
  ChildObj1: TChildObject1;
  ChildObj2: TChildObject2;
begin
  if TreeView1.Selected <> nil then
  begin
    if TreeView1.Selected.Text = 'Child Object 1' then
    begin
      ChildObj1 := TreeView1.Selected.Data;    
      Edit1.Text := ChildObj1.SomeString;
    end else
    if TreeView1.Selected.Text = 'Child Object 2' then
    begin
      ChildObj2 := TreeView1.Selected.Data;  
      Edit1.Text := IntToStr(ChildObj2.SomeInteger);
    end;
  end;
end;

提示和建议表示赞赏。

1 个答案:

答案 0 :(得分:5)

主要问题是您要释放要添加到树视图的对象的内存。因此,节点的数据指向无效的位置。

要将对象分配给节点,请使用像这样的代码

  Obj := TChildObject1.Create(aName);
  aTreeView.Items.AddObject(nil, Obj.Name, Obj);

当您需要处理数据时,可以为每个节点调用Free方法。

 for i:= 0 to TreeView1.Items.Count - 1 do
 begin
  Obj:= TMyObject(TreeView1.Items.Item[i].Data);
  if Assigned(Obj) then
   Obj.Free;
 end;