Search code examples
delphidelphi-2010delphi-xe4delphi-xe7

How to do generic typecasting in delphi?


I have a base class test define below

type
Tinfo = procedure of object;

Test = class(TObject)
public
  procedure Add    ( const a : Tinfo ); reintroduce ;
end;


procedure Test.Add(const a: Tinfo);
begin
  Writeln('base class add function');
  // dosomething more  
end;

and I have a derived generic class from this base class

TTesting<T> = class(Test)
   public
     procedure Add    ( const a : T  ); reintroduce ;
   end;

and I am typecasting T to Tinfo but it gives me the error

procedure TTesting<T>.Add(const a : T );
begin
  inherited Add(Tinfo(a) );  // gives me error here 
end;

is there any way I can implement this?


Solution

  • First your cast is wrong, you obviously want to cast a and not T.

    However if you want to type cast on a procedure of object which is a type that cannot be polymorphic in any way it makes no sense to put that into a generic type at all.

    What should T be? It only can be a TInfo in your code.

    If you however want T to be any event/method type you should store a TMethod in your base class and then work with that in your generic class. But remember that you cannot have a constraint that limits T to be an event type. So you might check that in your constructor.

    type
      PMethod = ^TMethod;
    
      Test = class(TObject)
      public
        procedure Add(const a: TMethod ); reintroduce ;
      end;
    
    procedure Test.Add(const a: TMethod);
    begin
      Writeln('base class add function');
      // dosomething more
    end;
    
    type
      TTesting<T> = class(Test)
      public
        constructor Create;
        procedure Add(const a: T); reintroduce ;
      end;
    
    constructor TTesting<T>.Create;
    begin
      Assert(PTypeInfo(TypeInfo(T)).Kind = tkMethod);
      inherited Create;
    end;
    
    procedure TTesting<T>.Add(const a: T);
    begin
      inherited Add(PMethod(@a)^);
    end;