[fpc-pascal] Generics - extending TFPGObjectList
Sven Barth
pascaldragon at googlemail.com
Thu Jul 26 07:04:42 CEST 2018
Am 26.07.2018 um 02:31 schrieb Vojtěch Čihák:
>
> Hello,
>
> I needed to extend TFPGObjectList and I found two wierd things (FPC
> 3.1.1 r39507):
>
> program project1;
>
> {$mode objfpc}{$H+}
>
> uses
>
> Classes, FGL;
>
> type
>
> TBaseClass = class (TObject)
>
> end;
>
> TIDClass = class (TBaseClass)
>
> ID: Integer;
>
> end;
>
> TNameIDClass = class (TIDClass)
>
> Name: string;
>
> end;
>
> generic TFPGObjectListEx<T: TIDClass> = class (specialize
> TFPGObjectList<TBaseClass>) //1 A
>
> function GetItemByID(AID: Integer): T;
>
> end;
>
> TNameIDList = class (specialize TFPGObjectListEx<TNameIDClass>)
>
> end;
>
> {$R *.res}
>
> function TFPGObjectListEx.GetItemByID(AID: Integer): T;
>
> begin
>
> {...}
>
> Result:=nil; //2
>
> end;
>
> var NameIDList: TNameIDList;
>
> NameID: TNameIDClass;
>
> begin
>
> NameID:=NameIDList.Items[0]; //1 B
>
> end.
>
> The demo does not compile because of two errors:
>
> 1) project1.lpr(38,21) Error: Incompatible types: got "TBaseClass"
> expected "TNameIDClass" at comment //1 B
>
> It is caused by declaration at //1 A. Class TFPGObjectListEx can be
> really generic only if it is declared like this:
>
> generic TFPGObjectListEx<T: TIDClass> = class (specialize
> TFPGObjectList<T>) //1 A, otherwise you must retype
> TNameIDClass(Items[0]) and it is against the philosophy of generics.
> Isn't it meaningless? Why there must be specialize to <T> when in fact
> it is no specialization at all.
>
You are not overriding the Items property, thus it will still be the
Items property of TFPGObjectList<TBaseClass> and thus the compiler will
rightfully complain at location 1 B. Using generics does not absolve you
from usual inheritance problems.
> 2) project1.lpr(32,11) Error: Incompatible types: got "Pointer"
> expected "$gendef4" at comment //2
>
> The line must be changed to
>
> Result:=T(nil);
>
> which seems bizarre to me, I've never seen retyping "nil". Even more,
> both TFPGObjectList and TFPGObjectListEx are constrained to TObject
> and to TIDClass so there is safety, TFPGObjectListEx can be only
> specialized with types that have "nil" (<T> can never be <Integer>,
> for example).
>
Well, no one said that the generics are completely bug free...
Especially in special situations that involve either Nil or type
constraints (or in this case both). Please provide a simple example and
open a bug report.
Regards,
Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20180726/588e006d/attachment.html>
More information about the fpc-pascal
mailing list