@Warfley But I kinda dont like "as" operator here.
In perfect world I'd like to write it without "as" operator.
Simply: moto:=motolist.getAO('yamaha r1');
The way you declared your classes that is the only way. But if you play around a bit more with generics you can do better:
program tgenlist;
{$mode objfpc}{$H+}
uses
fgl;
type
TAnyObject = class
end;
generic TGenAOList<T: TAnyObject> = class(specialize TFPGMap<String, T>)
end;
{ type for any TAnyObject descendant }
TAOList = specialize TGenAOList<TAnyObject>;
TCarObject = class(TAnyObject)
end;
TMotoObject = class(TAnyObject)
end;
TCarList = specialize TGenAOList<TCarObject>;
TMotoList = specialize TGenAOList<TMotoObject>;
var
cl: TCarList;
ml: TMotoList;
moto: TMotoObject;
begin
cl := TCarList.Create;
try
ml := TMotoList.Create;
cl.Add('subawu impreza', TCarObject.Create);
ml.Add('yamaha r1', TMotoObject.Create);
{ no "as" here }
moto := ml['yamaha r1'];
finally
cl.Free;
ml.Free;
end;
end.
Important caveat: you can
not pass a
TMotoList to something that takes a
TAOList (at least not without casting and based on the assumption that they have the same memory layout which in this situation is true and
shouldn't lead to problems).
Additional sidenote: you should use a
TFPGMapObject instead of
TFPGMap, because the former will free instances when they are deleted from the map (or the map itself is freed) otherwise you'd have to manually free them or have memory leaks.