Dave Novo 51 Posted Thursday at 02:31 PM Hello, If I make a list<T> where T is a record, what is the best way to get access to the actual records in the list to make modifications to them? If I was using the built in TList<T> I would use the .List<T>, but Spring4D.IList<T> does not have a property to access the raw list. Is there another way to get access to the actual record instance in the list in order to modify it. calling .Items makes a copy of the underlying record it seems and if I try to enumerate through the list using the enumerator and set a property on the variable in the enumerator I get an error that I cannot set a control loop variable. Share this post Link to post
Anders Melander 1815 Posted Thursday at 03:41 PM I don't use Spring4D but maybe you could create a record method that returns a pointer to the record: type PMyRecord = ^TMyRecord; TMyRecord ...lots of stuff here... function Data: PMyRecord; end; function TMyRecord.Data: PMyRecord; begin Result := @Self; end; begin var MyList := IList<TMyRecord>; ... var SomeData: PMyRecord := MyList[123].Data; ... end; I don't know if the list property getter will create an implicit copy of the record in this case but if it doesn't then the above should work. Share this post Link to post
Der schöne Günther 316 Posted Thursday at 06:15 PM IList<T> supports IArrayAccess<T>. Here's an example: procedure p(); type TRecord = record number: Byte; end; begin const items = TCollections.CreateList<TRecord>(); var item := Default(TRecord); item.number := 42; items.add(item); // Replace item at index 0 with a new one var newItem := items[0]; Inc(newItem.number); items[0] := newItem; WriteLn(items[0].number); // or use IArrayAccess<T> var arrayAccess: IArrayAccess<TRecord>; Assert( Supports(items, IArrayAccess<TRecord>, arrayAccess) ); Inc(arrayAccess.Items[0].number); WriteLn(items[0].number); end; Share this post Link to post
Anders Melander 1815 Posted Thursday at 06:40 PM 20 minutes ago, Der schöne Günther said: Assert( Supports(items, IArrayAccess<TRecord>, arrayAccess) ); Nice - but please don't use Assert like that in actual code. Share this post Link to post
Dave Novo 51 Posted Thursday at 08:25 PM It would be cool if the enumerator supported pointer access to the underlying element. Something like for var curPtr in List.Pointers<PRecord> do begin curPtr.SomeValue:=1; end In the case above, the Pointers record would return a pointer to the underlying item, cast to the pointer type passed in as T. This can be useful for records (and maybe other) to deal with a pointer to the underlying items Share this post Link to post
pyscripter 694 Posted Thursday at 08:39 PM (edited) 1 hour ago, Dave Novo said: It would be cool Spring4d does provide you with access to the array of values using IArrayAccess, but what you ask is not spring4d specific. It applies to any array of records. e.g. type TMyRec = record StrField: string; end; TMyRecArray = TArray<TMyRec>; To modify the values you need iterate using an index var RecArr: TMyRecArray for var I := 0 to Length(RecArr) - 1 do RecArray[I].StrField := ... Unfortunately you cannot do: for var Rec in RecArr do Rec.StrField := ... // <- compiler error: You cannot modify a for loop variable. and in any case what you get in Rec above is a copy of the record not the original one. I agree it would be cool to have an iterator that gives access to the underlying element. Edited Thursday at 09:35 PM by pyscripter Share this post Link to post
Stefan Glienke 2018 Posted Thursday at 09:33 PM (edited) 1 hour ago, Dave Novo said: It would be cool if the enumerator supported pointer access to the underlying element. I have something like that in the works already. 5 hours ago, Anders Melander said: I don't know if the list property getter will create an implicit copy of the record in this case but if it doesn't then the above should work. It does create a copy (records are value types, what else should it do?) - what you are proposing is dangerous and error-prone. 55 minutes ago, pyscripter said: Spring4d does provide you with access to the array of values using IArrayAccess, but what you ask is not spring4d specific. That is not the case anymore in 2.0 - that interface has been removed from lists. Edited Thursday at 09:40 PM by Stefan Glienke 1 Share this post Link to post
pyscripter 694 Posted Thursday at 09:35 PM Just now, Stefan Glienke said: I have something like that in the works already. Would that work with any TArray as well? Share this post Link to post