delphi - Writing a generic TList of records -


i trying write generic tlist contains records of specific type. starting david's answer on question, have written class:

type   tmerecordlist<t> = class(tlist<t>)   public type     p = ^t;   private     function getitem(index: integer): p;   public     procedure assign(source: tmerecordlist<t>); virtual;     function first: p; inline;     function last: p; inline;     property items[index: integer]: p read getitem;   end;  procedure tmerecordlist<t>.assign(source: tmerecordlist<t>); var   srcitem: t; begin   clear;   srcitem in source     add(srcitem); end;  function tmerecordlist<t>.first: p; begin   result := items[0]; end;  function tmerecordlist<t>.getitem(index: integer): p; begin   if (index < 0) or (index >= count)     raise eargumentoutofrangeexception.createres(@sargumentoutofrange);   result := @list[index]; end;  function tmerecordlist<t>.last: p; begin   result := items[count - 1]; end; 

having methods return pointer record works (not perfectly) pointers records can used if records in use cases. using record properties , setters, these test cases work expected:

  tmetestrecord = record   private     fid:     word;     ftext:   string;     fvalues: tintegers;     procedure setid(const value: word);     procedure settext(const value: string);     procedure setvalues(const value: tintegers);   public     property id: word read fid write setid;     property text: string read ftext write settext;     property values: tintegers read fvalues write setvalues;   end;    // testsetitem1   rl2[0] := rl1[0];    // testsetitem2   r.id     := 9;   r.text   := 'xxxx';   r.values := [9, 99, 999, 9999];   rl1[0]   := r;    // testassignempty (rl0 empty... after assign should rl2)   rl2.assign(rl0);    // testassigndeepcopies (modifications after assign should not affect both records)   rl2.assign(rl1);   r.id     := 9;   r.text   := 'xxxx';   r.values := [9, 99, 999, 9999];   rl1[0]   := r; 

problem 1 - modifying contained record

... test case compiles , runs not work desired:

  // testsetitemfields   rl1[0].id     := 9;   rl1[0].text   := 'xxxx';   rl1[0].values := [9, 99, 999, 9999]; 

modifications applied temporary copy of record , not 1 stored in list. know known , expected behaviour, documented in other questions.

but... there way around it? thinking maybe if tmerecordlist<>.items property had setter compiler maybe desired. it? know david has got solution, hinted @ in question... can't seem find on own.

this nice have, allow me have way of using list identical (or almost) of tlist of objects. having same interface means change objects records , viceversa, when need arises.

problem 2 - interface ambiguity

having tlist<> return record pointer pose interface ambiguity problems. tlist<> methods accept t parameters, , know being records, these going passed value. should these methods do? should rethink them? i'm talking these sets of methods:

  • remove , removeitem
  • extract , extractitem
  • contains indexof, indexofitem , lastindexof

there ambiguity how these should test contained items see if match parameter record value. list contain identical records , become source of bugs in user code.

i tried not deriving tlist<>, not have these methods, mess. couldn't write class similar tlist without writing own tlisthelper. unfortunately system.generics.collections's 1 has needed fields private, fcount, , cannot used outside unit.

problem 1

your items property not marked being default. hence erroneous code picking base class default property. add default keyword items property:

property items[index: integer]: p read getitem; default; 

problem 2

this consequence of deriving tlist<t>. not recommend doing that. encapsulate instance of tlist<t> , therefore define interface explicitly rather inheriting it. or implement list functionality directly in code. after all, it's not more wrapper around dynamic array.

for worth classes don't use tlist<t> @ decision happy when emba broke class in recent release.


Comments

Popular posts from this blog

amazon web services - S3 Pre-signed POST validate file type? -

c# - Check Keyboard Input Winforms -