Delphi delegate types are interfaces

I knew anonymous functions were implemented as interfaces.

This, I hadn’t thought about.

Thanks to @sglienke for 2011.
I’m only 13 years behind. :smiling_face_with_tear:


Quoting ::

Well, a few versions ago we got method references. You prolly know how they are implemented behind the scenes but let’s take a quick look at them. You can do something like (as defined in SysUtils):

type
  TFunc<T> = reference to function: T;

As you also may know this is a reference counted type. Guess how it is implemented? Correct, with an interface. This is similar to:

type
  IFunc<T> = interface
    function Invoke(): T;
  end;

You can even use those method reference types as Interface when you implement a class:

type
  TMyFuncClass = class(TInterfacedObject, TFunc<Integer>)
  public
    function Invoke: Integer;
  end;

Or you can inherit your interface from it (and of course implement that interface into your class):

type
  IFunc<T> = interface(TFunc<T>)
  end;

Thanks @Paul_McGee for the link.

I like the suggestion from @sglienke about property references, but I think that they’d be more useful if TWidget.SomeProperty was a property reference (using the class name, not the object name), and could be assigned to method references of type Func<T, TProp> or Proc<T, TProp>.

So if

type
  TWidget = class
  private
    FName: string;
  public
    property Name: string read FName write FName;
  end;

You could assign TWidget.Name to method references of type Func<TWidget, string> or Proc<TWidget, string>, or to a property reference of type Prop<TWidget, string>.

Property references could then be used for Bindings, or to make filter predicates or compare functions, etc. There would be no need for magic strings.

Eg, if:

class function TCompareFns.MakeCompareFn<T>(const ValueFn: Func<T, string>): TComparison<T>;
begin
  Result := function(const Item1, Item2: T): Integer
            begin
              Result := CompareText(ValueFn(Item1), ValueFn(Item2));
            end;
end;

you could say:

var WidgetCompare = TCompareFns.MakeCompareFn<TWidget>(TWidget.Name);
Display(WidgetList.Ordered(WidgetCompare));

.
I’m not sure what syntax you’d use for a property reference. Maybe:

type
  Prop<T, TProp> = reference to property<T, TProp>;

It would be good if the property reference assignments worked regardless of whether the property setter had a const or a value parameter.

It would be nice if a property reference also gave you access to the name of the property and other details from PropInfo.