English 中文(简体)
检查类名
原标题:
  • 时间:2009-02-09 16:25:12
  •  标签:

我不知道OWNER对象类别的名称。因此,我必须在我的代码中到处检查,例如这样:

if TObject(OWNER) is TFirstClass then begin
  TFirstClass(OWNER).FirstFunction;
  TFirstClass(OWNER).SecondFunction;
  ...
end else
if TObject(OWNER) is TSecondClass then begin
  TSecondClass(OWNER).FirstFunction;
  TSecondClass(OWNER).SecondFunction;
  ...
end;

Is there a better way? Because I must do this if condition in many place of the codes. All functions of TFirstClass and TSecondClass (which I have to run) are the same.

注意:我使用的是Delphi 5。

最佳回答

如果您无法访问 TFirstClass 和 TSecondClass,但仍想简化您的代码,这里有一个方法:

创建一个适配器基类:

type
  TMyAdapter = class(TObject)
  public
    procedure FirstMethod; virtual; abstract;
    procedure SecondMethod; virtual; abstract;
  end;

然后创建派生类TFirstClassAdapter和TSecondClassAdapter,并分别为它们提供对TFirstClass或TSecondClass实例的私有引用。添加一个设置此引用的构造函数。重写适配器类的方法,以便它们调用适配的类。

type
  TFirstClassAdapter = class(TMyAdapter)
  private
    fObject: TFirstClass;
  public
    constructor Create(AAdaptedObject: TFirstClass);

    procedure FirstMethod; override;
    procedure SecondMethod; override;
  end;

constructor TFirstClassAdapter.Create(AAdaptedObject: TFirstClass);
begin
  inherited Create;
  fObject := AAdaptedObject;
end;

procedure TFirstClassAdapter.FirstMethod;
begin
  fObject.FirstMethod;
end;

procedure TFirstClassAdapter.SecondMethod;
begin
  fObject.SecondMethod;
end;

另一个类也一样。现在你只需要决定是创建一次适配器并传递它,还是创建一个需要时随处调用的函数,并为你的具体类提供一个适配器。

如果你使用接口实现适配器,那么你甚至不需要自己管理适配器的生命周期。

通过这种方式,您可以拥有Ulrich在他的答案中提供的多态行为,但无需更改TFirstClass和TSecondClass。

问题回答

从一个公共基类派生TFirstClass和TSecondClass,该基类声明了虚拟方法FirstFunction和SecondFunction。

乌利 (Wūlì)

At first excuse-me for my bad english.
If you can t do the 2 before responses (Adapters and derive from a base class), you can use RTTI to access a procedure by it s name.

这个过程必须在发布部分声明。

如果您有像这样的声明:

  TFirstClass = class(TObject)
  published
    procedure FirstFunction;
    procedure SecondFunction;
  end;
  TSecondClass = class(TObject)
  published
    procedure FirstFunction;
    procedure SecondFunction;
  end

如果你有名称,可以这样做来执行一个方法:

  // Acceso a la rutina; TObject is a Base class for 
  // TFirstClass and TSecondClass
  Routine.Data := Pointer(obj as TObject);
  // Devuelve la dirección de un método published; Method for it s name
  Routine.Code := (obj as TObject).MethodAddress( SecondFunction );
  // Not find
  if (Routine.Code = nil) then Exit;
  // execute
  TExecuteMethod(Routine);

You can see similar codes here:
* Tip4 * Tip7

问候。





相关问题
热门标签