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?
source to share
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.
source to share
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.
source to share
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;
source to share