德尔福 - 如何超载' '对象的过程'类型

时间:2014-11-04 10:18:35

标签: delphi delphi-xe4 overloading

德尔福'提供任何超载的方法。 '对象的过程'类似

TTesting = class(TObject)
Public
Type
TInformationEvent1 = procedure( x: integer ) of object; overload ;
TInformationEvent1 = procedure ( x: integer ; y: string) of object; overload ;
TInformationEvent1 = procedure ( x: integer ; y: string; z: Boolean) of object; overload ;
end

我可以用这三种方式重载这个TInformationEvent1函数吗?

3 个答案:

答案 0 :(得分:8)

不同的类型必须具有不同的名称,因为@ user246408的评论已经说明了。因此,您必须为每个类型指定一个不同的名称,例如:

type
  TInformationEvent = procedure(X: Integer) of object;
  TInformationEventS = procedure(X: Integer; Y: string) of object;
  TInformationEventSB = procedure(X: Integer; Y: string; Z: Boolean) of object;

现在,您可以将任何方法(对象的过程)与匹配的签名分配给其中一种类型的实例。因此,您分配的方法可能是重载,但类型不能重载。

答案 1 :(得分:8)

好吧。您可以定义具有相同名称但不同数量的类型参数的泛型类型。

type
  TInformationEvent<T> = procedure(x:T) of object;
  TInformationEvent<T1,T2> = procedure(x:T1;y:T2) of object;
  TInformationEvent<T1,T2,T3> = procedure(x:T1; y:T2; z:T3) of object;

当您将其中一个作为类的成员添加时,您需要解析类型参数。

type
  TMyClass = class
  private
    FMyEvent: TInformationEvent<Integer>;
    FMyEvent2: TInformationEvent<Integer,string>;
  public
    property MyEvent: TInformationEvent<Integer> read FMyEvent write FMyEvent;
    property MyEvent2: TInformationEvent<Integer,string> read FMyEvent2 write FMyEvent2;
  end;

就编译器而言,这些是技术上不同的命名类型,但从开发人员的角度来看,您不需要为每种类型提供唯一的名称。请注意,overload关键字的使用是不必要的,实际上是在定义过程类型时使用的语法错误。 Overload具有非常特定的含义:ad hoc多态性。这不是它。

请注意,如果您正在编写组件或控件并希望制作这些已发布的属性,则您的里程可能会有所不同。表单设计者对泛型有很多支持。

答案 2 :(得分:3)

方法指针类型的

Procedural types,如您所示,通常需要输入事件属性。

重载事件属性的类型是不可能的,没有用处,因为事件属性专门用于执行单个操作。

另一方面,例程的重载可能很有用,因为您需要在多个功能之间进行选择。

否则说:事件处理程序和其他例程之间的区别在于事件处理程序无法控制输入。

  

你能用一个小例子解释一下吗?

是的,我可以。这里有一个包含三个连续属性的类,每个属性都具有比前一个更多的功能。您作为用户可以选择分配其中一个或全部。

type
  TTest = class(TObject)
  type
    TInfoEvent1 = procedure(X: Integer) of object;
    TInfoEvent2 = procedure(X: Integer; Y: String) of object;
    TInfoEvent3 = procedure(X: Integer; Y: String; Z: Boolean) of object;
  private
    FOnInfo1: TInfoEvent1;
    FOnInfo2: TInfoEvent2;
    FOnInfo3: TInfoEvent3;
  protected
    procedure DoInfo(X: Integer; Y: String; Z: Boolean);
  public
    property OnInfo1: TInfoEvent1 read FOnInfo1 write FOnInfo1;
    property OnInfo2: TInfoEvent2 read FOnInfo2 write FOnInfo2;
    property OnInfo3: TInfoEvent3 read FOnInfo3 write FOnInfo3;
  end;

  TForm2 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    FTest: TTest;
    procedure Info(X: Integer); overload;
    procedure Info(X: Integer; Y: String; Z: Boolean); overload;
  end;

implementation

{$R *.dfm}

{ TTest }

procedure TTest.DoInfo(X: Integer; Y: String; Z: Boolean);
begin
  if Assigned(FOnInfo3) then
    FOnInfo3(X, Y, Z)
  else if Assigned(FOnInfo2) then
    FOnInfo2(X, Y)
  else if Assigned(FOnInfo1) then
    FOnInfo1(X);
end;

{ TForm2 }

procedure TForm2.FormCreate(Sender: TObject);
begin
  FTest := TTest.Create;
  FTest.OnInfo1 := Info;
  FTest.OnInfo3 := Info;
end;