<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <div class="moz-cite-prefix">Am 26.07.2018 um 02:31 schrieb Vojtěch
      Čihák:<br>
    </div>
    <blockquote type="cite" cite="mid:20180726023153.4044CD7C@atlas.cz">
      <meta http-equiv="content-type" content="text/html; charset=utf-8">
      <p style="padding:0 0 0 0; margin:0 0 0 0;">Hello,</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;"> </p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">I needed to
        extend TFPGObjectList and I found two wierd things (FPC 3.1.1
        r39507):</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;"> </p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">program project1;</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">{$mode objfpc}{$H+}</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;"> </p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">uses</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">  Classes, FGL;</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;"> </p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">type</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">  TBaseClass = class
        (TObject)</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">  end;</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;"> </p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">  TIDClass = class
        (TBaseClass)</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">    ID: Integer;</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">  end;</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;"> </p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">  TNameIDClass = class
        (TIDClass)</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">    Name: string;</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">  end;</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;"> </p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">  generic
        TFPGObjectListEx<T: TIDClass> = class (specialize
        TFPGObjectList<TBaseClass>) //1 A</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">    function
        GetItemByID(AID: Integer): T;</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">  end;</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;"> </p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">  TNameIDList = class
        (specialize TFPGObjectListEx<TNameIDClass>)</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;"> </p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">  end;</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;"> </p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">{$R *.res}</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;"> </p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">function
        TFPGObjectListEx.GetItemByID(AID: Integer): T;</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">begin</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">  {...}</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">  Result:=nil; //2</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">end;</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;"> </p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">var NameIDList:
        TNameIDList;</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">    NameID:
        TNameIDClass;</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">begin</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;"> 
        NameID:=NameIDList.Items[0]; //1 B</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">end.</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;"> </p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">The demo does not
        compile because of two errors:</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;"><span
          style="font-size: 10pt;">1) </span>project1.lpr(38,21) Error:
        Incompatible types: got "TBaseClass" expected "TNameIDClass" at
        comment //1 B</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">It is caused by
        declaration at //1 A. Class <span style="font-size: 13.3333px;">TFPGObjectListEx
          can be really generic only if it is declared like this:</span></p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">   generic
        TFPGObjectListEx<T: TIDClass> = class (specialize
        TFPGObjectList<T>) //1 A, otherwise you must retype <span
          style="font-size: 13.3333px;">TNameIDClass(</span><span
          style="font-size: 10pt;">Items[0]) and it is against the
          philosophy of generics. I</span><span style="font-size: 10pt;">sn't
          it meaningless? Why there must be specialize to <T> when
          in fact it is no specialization at all.</span></p>
    </blockquote>
    <br>
    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.<br>
    <br>
    <blockquote type="cite" cite="mid:20180726023153.4044CD7C@atlas.cz">
      <p style="padding:0 0 0 0; margin:0 0 0 0;"> </p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">2) project1.lpr(32,11)
        Error: Incompatible types: got "Pointer" expected "$gendef4" at
        comment //2</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">The line must be
        changed to</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">  Result:=T(nil);</p>
      <p style="padding:0 0 0 0; margin:0 0 0 0;">which seems bizarre to
        me, I've never seen retyping "nil". Even more, both <span
          style="font-size: 13.3333px;">TFPGObjectList and </span><span
          style="font-size: 13.3333px;">TFPGObjectListEx are constrained
          to TObject and to TIDClass so there is safety, </span><span
          style="font-size: 13.3333px;">TFPGObjectListEx can be only
          specialized with types that have "nil" (<T> can never be
          <Integer>, for example).</span></p>
    </blockquote>
    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.<br>
    <br>
    Regards,<br>
    Sven<br>
  </body>
</html>