Delphi - 如何“重载”“procedure of object”类型

3

Delphi提供了类似于以下代码的“procedure of object”类型的“overload”重载方法吗?

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函数吗?


9
你可以像重载普通过程一样重载对象的过程,但是你正在尝试重载一个 类型,这毫无意义。 - kludg
你能用一个小例子来解释一下吗? - akash_27
3
你想做什么?还是只是出于好奇? - NGLN
3个回答

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;

现在您可以将具有相匹配签名的任何方法(对象的过程)分配给这些类型的实例。因此,您分配的方法可以是重载,但类型不能被重载。


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有一个非常具体的含义:临时多态。这不是它的用法。
请注意,如果您正在编写组件或控件,并希望将这些发布属性变成可用的,则可能会因为泛型的支持不稳定而受到影响。

3

过程类型,像你展示的那样,通常用于事件属性的类型。

重载一个事件属性的类型是不可能的,并且也没有任何用处,因为事件属性被专门设计只做一件事。

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

换句话说:事件处理程序与其他例程之间的区别在于,在事件处理程序中,您无法控制输入。

能否举一个小例子来解释一下?

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

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;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接