Dave Novo 52 Posted December 19, 2024 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 1837 Posted December 19, 2024 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 322 Posted December 19, 2024 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 1837 Posted December 19, 2024 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 52 Posted December 19, 2024 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 703 Posted December 19, 2024 (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 December 19, 2024 by pyscripter Share this post Link to post
Stefan Glienke 2026 Posted December 19, 2024 (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 December 19, 2024 by Stefan Glienke 1 Share this post Link to post
pyscripter 703 Posted December 19, 2024 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