delphigenericsdelphi-xe4

Delphi - How can I pass Generic parameter to function that accept Array of const parameter


I have a 'Base class' which contain a 'function' that accept parameter of type 'Array of const' as shown below:-

type
  TBaseClass = class(TObject)
  public
    procedure NotifyAll(const AParams: array of const);
  end;

procedure TBaseClass.NotifyAll(const AParams: array of const);
begin
  // do something
end;

I have another 'Generic class' that is derived from the 'base class' ( defined above )

type
  TEventMulticaster<T> = class(TBaseClass)
  public
    procedure Notify(AUser: T); reintroduce;
  end;

procedure TEventMulticaster<T>.Notify(AUser: T);
begin
  inherited NotifyAll([AUser]);   ERROR HERE
end;

Every time I compile this code it gives error saying:

Bad argument type in variable type array constructor

What does it referring to be wrong?


Solution

  • You cannot pass a Generic argument as a variant open array parameter. The language Generics support simply does not cater for that.

    What you can do instead is wrap the Generic argument in a variant type, for instance TValue. Now, you cannot pass TValue instances in a variant open array parameter either, but you can change NotifyAll() to accept an open array of TValue instead:

    procedure NotifyAll(const AParams: array of TValue);
    

    Once you have this in place, you can call it from your Generic method like so:

    NotifyAll([TValue.From<T>(AUser)]);
    

    Fundamentally, what you are attempting to do here is combine compile-time parameter variance (Generics) with run-time parameter variance. For the latter, there are various options. Variant open array parameters are one such option, but they do not play well with Generics. The alternative that I suggest here, TValue, does have good interop with Generics.