Delphi - How to "overload" an object type procedure

Do 'Delphi' provides any way to "overload" an "object type procedure" like

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

      

Can I overload this TInformationEvent1 function in three ways?

+3


source to share


3 answers


Good. You can define generic types with the same name but a different number of type arguments.

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;

      

Then you will need to resolve the type argument when adding one of these as a member of the class.



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;

      

These are technically different named types as far as the compiler is concerned, but from a developer's point of view, you don't need to create unique names for each type. Note that the use of the keyword overload

is unnecessary and is actually a syntax error when defining procedural types. overload

has a very specific meaning: ad hoc polymorphism. This is not true.

Note. If you are writing a component or control and want to make these published properties, your mileage may vary. The form designer has spotty generics support.

+8


source


The different types must have different names, as the comment of user @ user246408 already says. Therefore, you will need to give each of these types a different name, for example:

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;

      



Now you can assign any method (object procedure) with the appropriate signature to instances of one of these types. Thus, the methods you assign can be overloads, but types cannot be overloaded.

+8


source


Procedural types of the method pointer type, as you have shown, are usually required for injecting event properties.

Overloading the event property type is not possible and will not be used since the event property is specifically designed to do one thing.

Subroutine overloading, on the other hand, can be useful because you need to choose between multiple functionality.

Otherwise it is said: The difference between an event handler and other routines is that with event handlers you have no control over the entry.

Can you explain this with a small example?

Yes I can. Here you have a class with three sequential properties, each with more functionality than the last. You, as a user, have the option to designate one or all of them.

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;

      

+3


source







All Articles