简体   繁体   English

检查班级名称

[英]Check class name

I don't know OWNER object class name. 我不知道OWNER对象类名。 So I must check everywhere in my codes like that : 所以我必须检查我的代码中的所有地方:

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. TFirstClass和TSecondClass(我必须运行)的所有功能都是相同的。

Note : I use Delphi 5. 注意:我使用的是Delphi 5。

If you have no access to TFirstClass and TSecondClass, but still want to simplify your code, here's a way: 如果您无法访问TFirstClass和TSecondClass,但仍希望简化代码,可以采用以下方法:

Create an adapter base class: 创建适配器基类:

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

Then create descendant classes TFirstClassAdapter and TSecondClassAdapter and give them each a private reference to the instance of TFirstClass or TSecondClass respectively. 然后创建子类TFirstClassAdapter和TSecondClassAdapter,并分别为它们提供对TFirstClass或TSecondClass实例的私有引用。 Add a constructor which sets this reference. 添加一个设置此引用的构造函数。 Override the methods of the adapter classes, so that they call through to the adapted classes. 覆盖适配器类的方法,以便它们调用适应的类。

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;

Same for the other class. 对于其他班级也是如此。 Now you only need to decide whether you create the adapter once and pass it around, or whether you make a function that you call everywhere you need it, and which will give you an adapter for your concrete class. 现在你只需要决定是否创建一次适配器并传递它,或者你是否创建了一个你需要它的地方调用的函数,它将为你的具体类提供适配器。

If you implement the adapter using interfaces, then you will not even need to manage the lifetime of the adapter yourself. 如果使用接口实现适配器,那么您甚至不需要自己管理适配器的生命周期。

This way you can have the polymorphic behaviour that Ulrich gave in his answer , but without the need to change TFirstClass and TSecondClass. 通过这种方式,您可以获得Ulrich在其答案中提供的多态行为,但无需更改TFirstClass和TSecondClass。

Derive TFirstClass and TSecondClass from a common base class that declares virtual methods FirstFunction and SecondFunction. 从公共基类派生TFirstClass和TSecondClass,该基类声明虚方法FirstFunction和SecondFunction。

Uli. 乌利。

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. 如果您无法在响应之前执行2(适配器并从基类派生),则可以使用RTTI按名称访问过程。

The procedure must be declared in the published section. 该程序必须在已发布的部分中声明。

If you've a declaration like this: 如果您有这样的声明:

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

You can do something like this to execute a method if you have the name: 如果你有这个名字,你可以做这样的事情来执行一个方法:

  // 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 * Tip4 * Tip7

Regards. 问候。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM