0

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?

daniele3004
  • 13,072
  • 12
  • 67
  • 75
john nash
  • 49
  • 1
  • 9
  • you try to cast the type identifier. you have to cast `a` (the variable), not `T` (the type of `a`). but i this is unsafe! and i am not sure if your code works anyway. what do you want to do? maybe there is another/better approach to do it. – linluk Nov 10 '14 at 11:05
  • 1
    You've asked this question so many times. Why won't you tell us the real problem? – David Heffernan Nov 10 '14 at 11:15
  • 1
    Why the `reintroduce` on `Add`in the first object? TObject does not have a virtual method called `Add`. So let me guess: this is not your real code. And what you are trying to do makes no sense. What is your obsession with function pointers? – Rudy Velthuis Nov 10 '14 at 21:37

1 Answers1

1

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;
Stefan Glienke
  • 20,860
  • 2
  • 48
  • 102
  • T is always of type procedure of object but it can accept integer , string or both . – john nash Nov 10 '14 at 11:10
  • a `procedure of object` cannot accept anything, its the definition of a parameterless method. This is still the same problem as in your other questions some days ago. You need to understand that method types (or rather invokable types at all) not easily work with generics. – Stefan Glienke Nov 10 '14 at 11:11
  • when i say accept i mean it can be of type TInformationEvent1 = procedure ( x: integer ) of object ; TInformationEvent2 = procedure ( x: integer ; y: string ) of object; TInformationEvent6 = procedure ( x: boolen ; y: string ) of object; – john nash Nov 10 '14 at 11:12
  • To me it looks like you want to build something like the multicast events we offer in Spring4D. I suggest you look into these before banging your head against the wall much more. :) – Stefan Glienke Nov 10 '14 at 11:15
  • @Stefan, hard to say. The OP rejected [`this option`](http://stackoverflow.com/a/26650905/960757) some time ago. – TLama Nov 10 '14 at 15:15