JohnLM 27 Posted 16 hours ago (edited) I've been wondering about this for some time and now I need to iterate over the strings to view them but I can't when using TStrings. And the only way to do it is to create a temporary TStringList var and assign the TStrings over to it. Then, I can step through the list to observe what is going on during debug. It seems like extra work to me. Anyway. See below for ex of how I have to create the extra work. It is not the actual code but just an example of some of it. function inlist(myts: tstrings): tstringlist; var tsL: tstringlist; begin myts := tstrings.create(self) tsL := tstringlist.create; tsL.assign(myts); . . s:=s; // <-- debug breat point result.assign(tsL); tsL.free; end; procedure TForm1.btn3Click(Sender: TObject); var ts: tstrings; begin ts := tstringlist.create; ts := inlist(memo1.lines) . . ts.free; end; In tstringlist, there is a FList that holds the strings. I searched in tstrings but there is none. Surely, tstrings is storing the strings somewhere. I just need to know where so I can view them during debugging. Does anyone know where tstrings stores the strings? Edited 16 hours ago by JohnLM added addtional code snippets Share this post Link to post
Olli73 7 Posted 16 hours ago From the documentation: Derive a class from TStrings to store and manipulate a list of strings. TStrings contains abstract or, in C++ terminology, pure virtual methods and should not be directly instantiated TStrings does not hold any string, it should be treated as abstract class, you must always inititae a derived class of it, which implements the data (string) storing. Share this post Link to post
Remy Lebeau 1659 Posted 8 hours ago (edited) 8 hours ago, JohnLM said: I've been wondering about this for some time and now I need to iterate over the strings to view them but I can't when using TStrings. And the only way to do it is to create a temporary TStringList var and assign the TStrings over to it. Then, I can step through the list to observe what is going on during debug. It seems like extra work to me. TStrings is an abstract base class. You cannot instantiate it directly (as your example is trying to do), and it does not hold any data of its own. It is the responsibility of descendant classes to decide how to handle the strings as they need. For instance, TStringList holds its strings in a memory list (as you noted), whereas TComboBox stores its strings inside of its window, whereas TRadioGroup exposes its strings as captions of child buttons, etc. If you want to view the entire contents of a base TStrings at debug time, then if you KNOW the TStrings is actually a TStringList then you can simply type-cast and debug it directly. Otherwise, you must copy the individual strings into something that is viewable in the debugger, like TStringList. TStrings itself does not hold any data that can be viewed directly. Otherwise, you can use the TStrings's properties to iterate and view the individual strings, eg: function inlist(myTs: TStrings): TStringList; var s: string; i: Integer; ts: TStringList; begin Result := TStringList.Create; try if myTs is TStringList then begin ts := TStringList(myTs); ... Result.Assign(ts); // <-- debug breakpoint end else begin for i := 0 to myTs.Count-1 do begin s := myTs.Strings[i]; ... Result.Add(s); // <-- debug breakpoint end; end; except Result.Free; raise; end; end; 8 hours ago, JohnLM said: Anyway. See below for ex of how I have to create the extra work. It is not the actual code but just an example of some of it. The code you have shown does not even compile, as TStrings does not have a constructor that takes a parameter. But even if the code did compile, what your code is doing is just plain wrong, as it is creating memory leaks and accessing invalid memory. It should look more like this instead: function inlist(myts: TStrings): TStringList; var tsL: TStringList; begin tsL := TStringList.Create; try tsL.Assign(myts); except tsL.Free; raise; end; Result := tsL; // <-- debug breakpoint end; procedure TForm1.btn3Click(Sender: TObject); var ts: TStringList; begin ts := inlist(Memo1.Lines); try ... finally ts.Free; end; end; Quote In tstringlist, there is a FList that holds the strings. I searched in tstrings but there is none. Surely, tstrings is storing the strings somewhere. Nope. TStrings itself doesn't even know the strings exist, let alone where they are stored. The descendant classes handle those details. Quote Does anyone know where tstrings stores the strings? Nowhere at all. Edited 7 hours ago by Remy Lebeau Share this post Link to post