Delegates

Top  Previous  Next

Delegate is a data structure that refers to a static method or to a class instance and an instance method of that class. 

The closest equivalent of a delegate in Delphi Win32 is the method pointer.

 

 

Procedural Types and Procedure Pointers

SmartMS lets you treat routines (functions and procedures) as values that can be assigned to variables.

Consider the nest code segment: 

 

 

Method Pointers

Similar to procedural pointers, method pointers reference a method of an instance object.

Here's one method pointer example: 

 

 

 

Function pointers are unified, there is no distinction between standalone function and method pointers. 

For instance the following code is valid as long as the function or method prototype matches. 

 

type

  TMyFunction = function(n: Integer): string;

 

type

  myMethodDelegate = function(myInt: Integer): string of object;

//-----------------------------------------------------------------

  TmySampleClass = class

  public

    function myStringMethod (myInt: Integer): string;

    class function mySignMethod (myInt: Integer): string; static;

  end;

 

{ mySampleClass }

 

class function TmySampleClass.mySignMethod

         (myInt: Integer): string;

begin

  Result := '';

  if (myInt > 0then Result := '+';

  if (myInt < 0then Result := '-';

end;

 

function TmySampleClass.myStringMethod

         (myInt: Integer): string;

begin

  Result := 'zero';

  if (myInt > 0then Result := 'positive';

  if (myInt < 0then Result := 'negative';

end;

 

procedure TForm1.W3Button7Click(Sender: TObject);

var

  mySC: TmySampleClass;

  x: myMethodDelegate;

  y: myMethodDelegate;

  IntegerToString : TMyFunction;

 

begin

  IntegerToString := IntToStr;

  WriteLn(IntegerToString(12345));

 

  mySC := TmySampleClass.Create;

 try

  WriteLn(Format('%d is %d; use the sign %d',[5,  mySC.myStringMethod(5),  mySC.mySignMethod(5)]) );

  WriteLn(Format('%d is %d; use the sign %d',[-3, mySC.myStringMethod(-3), mySC.mySignMethod(-3)]) );

  WriteLn(Format('%d is %d; use the sign %d',[0,  mySC.myStringMethod(0),  mySC.mySignMethod(0)]) );

  WriteLn(sLineBreak);

 

  { Using Delegates }

  x := mySC.myStringMethod;

  y := mySC.mySignMethod;

  WriteLn(Format('%d is %d; use the sign %d',[5,   x(5),  y(5) ]) );

  WriteLn(Format('%d is %d; use the sign %d',[-3, x(-3),  y(-3)]) );

  WriteLn(Format('%d is %d; use the sign %d',[0,   x(0),  y(0) ]) );

 

 finally

    mySC.Free;

 end;

end;

 

As long as the function or method prototype matches.

You can use the @ operator to explicitly access a function reference to remove ambiguity. 

 

 

 SmartMS nested routine example.

 

The function pointers and closures are unified, you don’t have to distinguish between a procedure and a procedure  of  object, 

and you don’t have to distinguish a reference  to  procedure either. 

 

 

See Anonymous methods