Delphi Generic Template classes Usage Compilation Error -


i new delphi generic classes. don't of how use generic classes in implementation code. here code:

type tdataelement = class(tobject)   protected     procedure setname(snewvalue:string); virtual;   private     m_sname:string;   published     property sname:string read m_sname write setname; end;  type tdataarray<t : tdataelement> = class(tobject)   public      function find(dtelement:t):integer;      procedure add(dtelement:t);   private     m_vcontainer : array of t;   protected     function getdata(index:integer):t; virtual;     procedure setdata(index:integer; newvalue:t); virtual;   public     property vdata[index: integer]: t read getdata write setdata; end;  implementation  function tdataarray<t>.find(dtelement:t):integer; var i:integer; begin   result:=-1;   := 0 high(m_vcontainer)     if (m_vcontainer[i] <> nil)and(m_vcontainer[i] = dtelement)     begin       result:=i;       exit;     end; end;     ..... 

when try create instances of generic classes in following code: method1)

var z:tdataarray<tdataelement>;     z:=tdataarray<tdataelement>.create(); 

i following error:

e2010 incompatible types: 'tdataelement' , 'class of tdataelement'

if 2nd method strange error: method 2) type tdataelementclass = class of tdataelement;

var  z:tdataarray<tdataelementclass>; 

f2084 internal error : i8230

what doing wrong?

entire source code in 1 file

  system.sysutils,classes,   dtarray_unit in 'd:\visionbot\software\visionbot\gui\units\dtarray_unit.pas';   type tdataelement = class(tobject)   protected     procedure setname(snewvalue:string); virtual;   private     m_sname:string;   published     property sname:string read m_sname write setname; end;  type tdataarray<t : tdataelement> = class(tobject)   public      function find(dtelement:t):integer; overload;      procedure add(dtelement:t);   private      m_vcontainer : array of t;   protected     function getdata(index:integer):t; virtual;     procedure setdata(index:integer; newvalue:t); virtual;   public     property vdata[index: integer]: t read getdata write setdata; end;  type   tderiveddataelement = class(tdataelement)   end;  var   z2: tdataarray<tderiveddataelement>;   //------------------------------------------------------------------------------ procedure tdataelement.setname(snewvalue:string); begin   self.m_sname:=snewvalue; end; //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ function tdataarray<t>.find(dtelement:t):integer; var i:integer; begin   result:=-1;   := 0 high(m_vcontainer)     if (m_vcontainer[i] <> nil)and(m_vcontainer[i] = dtelement)     begin       result:=i;       exit;     end; end; //------------------------------------------------------------------------------ function tdataarray<t>.getdata(index:integer):t; begin   result:=nil;   if index < 0 exit else   if index > high(index) exit else   result:=self.m_vcontainer[index]; end; //------------------------------------------------------------------------------ procedure tdataarray<t>.add(dtelement:t); begin   setlength(self.m_vcontainer,length(m_vcontainer)+1);   m_vcontainer[high(m_vcontainer)]:=t; end; //------------------------------------------------------------------------------ procedure tdataarray<t>.setdata(index:integer; newvalue:t); begin   if index < 0 exit else   if index > high(index) exit else   self.m_vcontainer[index]:=t;  end; //------------------------------------------------------------------------------   begin   try      z2:= tdataarray<tderiveddataelement>.create();      readln;   except     on e: exception       writeln(e.classname, ': ', e.message);   end; end. 

var     z: tdataarray<tdataelementclass>; 

the problem tdataelementclass not class derived tdataelement.

the following valid:

var     z: tdataarray<tdataelement>; 

or this:

type   tderiveddataelement = class(tdataelement)   end;  var     z: tdataarray<tderiveddataelement>; 

in code have

type   tdataelementclass = class of tdataelement; 

now, tdataelementclass metaclass.

  • a variable of type tdataelement can hold instance of type tdataelement, or instance of class derived tdataelement.
  • a variable of type tdataelementclass can hold type, must tdataelement, or class derived tdataelement.

you claim in question using tdataarray<tdataelement> leads compiler error, not true. consider compiling program:

type   tdataelement = class   end;  type   tdataarray<t: tdataelement> = class   public     function find(dtelement: t): integer;   private     m_vcontainer: array of t;   end;  function tdataarray<t>.find(dtelement: t): integer; begin   result := 0 high(m_vcontainer)     if (m_vcontainer[result] <> nil) , (m_vcontainer[result] = dtelement)       exit;   result := -1; end;  var   arr: tdataarray<tdataelement>;  begin   arr := tdataarray<tdataelement>.create; end. 

in edit show code:

procedure tdataarray<t>.add(dtelement:t); begin   setlength(self.m_vcontainer,length(m_vcontainer)+1);   m_vcontainer[high(m_vcontainer)]:=t; end; 

the erroneous line here:

m_vcontainer[high(m_vcontainer)]:=t; 

this fails because t type rather instance. think mean:

m_vcontainer[high(m_vcontainer)]:=dtelement; 

Comments