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 typetdataelement
, or instance of class derivedtdataelement
. - a variable of type
tdataelementclass
can hold type, musttdataelement
, or class derivedtdataelement
.
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
Post a Comment