Forum > General

Problem when casting with a generic type

(1/1)

Basile B.:
Hello, I'm thinking about refactoring a program using the standard observer pattern, based on generics and simple non-COM interfaces. The problem is that FPC (either 2.6.4 or latest trunk) doesn't seem to accept the parameterized type to cast:

I've attached the full source as it's a simple console program test, however the subject class declaration looks like this, (ITF is the observer interface):

--- Code: ---  generic TGenericEmitter<ITF> = class(IInfoEmitter)
  protected
    fReceivers: TObjectList;
    function acceptReceiver(aObject: TObject): boolean; virtual; // test for ITF
    function getReceiver(index: Integer): ITF;
  public
    constructor create;
    destructor destroy; override;
    //
    procedure updateReceivers; virtual;
    procedure addReceiver(aReceiver: TObject);
    procedure removeReceiver(aReceiver: TObject);
    //
    property receiver[index: integer]: ITF read getReceiver;
  end;

--- End code ---

and the implementation:

--- Code: ---constructor TGenericEmitter.create;
begin
  fReceivers := TObjectList.create(false);
end;

destructor TGenericEmitter.destroy;
begin
  fReceivers.Free;
  inherited;
end;

function TGenericEmitter.getReceiver(index: Integer): ITF;
begin
  // ouch 1:Error: Class or interface type expected, but got "<undefined type>"
  result := (fReceivers.Items[index] as ITF);
end;

function TGenericEmitter.acceptReceiver(aObject: TObject): boolean;
begin
  // ouch 2:Error: Class or interface type expected, but got "<undefined type>"
  result := (aObject as ITF) <> nil;
end;

procedure TGenericEmitter.addReceiver(aReceiver: TObject);
begin
  if fReceivers.IndexOf(aReceiver) <> -1 then
    exit;
  if not acceptReceiver(aReceiver) then
    exit;
  fReceivers.Add(aReceiver);
end;

procedure TGenericEmitter.updateReceivers;
begin
end;

procedure TGenericEmitter.removeReceiver(aReceiver: TObject);
begin
  fReceivers.Remove(aReceiver);
end;

--- End code ---

What's the right syntax to get rid of those errors ?

taazz:
I have never used generics so this is a bit trial and error but can you try to declare like this

--- Code: ---generic TGenericEmitter<T:ITF> = class(IInfoEmitter)
...
--- End code ---

Basile B.:
alas this does not do the trick.

guest58172:

--- Quote from: taazz on August 17, 2014, 10:09:34 pm ---I have never used generics so this is a bit trial and error but can you try to declare like this

--- Code: ---generic TGenericEmitter<T:ITF> = class(IInfoEmitter)
...
--- End code ---

--- End quote ---

It works finally:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program Project1;{$Mode objfpc}{$Interfaces CORBA} type  IDummy = interface  end;   ISomething = interface(IDummy)    function test(value: TObject): boolean;  end;   generic TTest<T:IDummy> = class    function test(value: TObject): boolean;  end;   TSomething = specialize TTest<ISomething>; function TTest.test(value: TObject): boolean;begin  result := value is T;end; beginend.   
Thx...

Navigation

[0] Message Index

Go to full version