Just a tip: Maybe the use of TStringList is just to use .indexOf(MyString)
to look for an item.
In such case, moving code to TObjectList is a total madness, you must re-invent the wheel, better said, the look on the list.
My recommendation is that it is better to avoid at all setting an object pointer to what is not an object, it is very easy to put a cat from Integer to Pointer, but it is also better to create an TIntegerObject
that holds such integer (not in terms of speed and memory, just in terms of not breaking the definitions).
I must explain such: If you store an Integer (not an object) where an Object is supposed to be, you are prone in a future to get pointer error operations when by error you forgot that pointer does not point to anything.
Oh, and there is another thing you loose by just casting: Knowing it it has a valid value or not; that is because Integer(Nil) equals value zero, so you can not know if you have a Nil or a zero value cast as an object pointer.
If you want it very simplified, aka without property, get ans set methods, etc, here is a sample:
TIntegerObject=class(TObject)
public
value:Integer;
constructor Create(value:Integer);
end;
TIntegerObject.Create(value:Integer);
begin
inherited Create;
Self.value:=value;
end;
It is a very basic class to store an integer as an object, there is no need for it to have a destructor since inside it there is nothing created that need to be free.
Then when you want to store an Integer onto the Objects of a TStringList you simply do:
MyStringList.Objects[MyIndex]:=TIntegerObject.Create(MyIntegerValue);
You can get the index for a known string value just with:
MyIndex:=MyStringList.IndexOf(MyString);
Then check it it returns -1
, that means such string is not on the list, it it is greater it means the string is on that position of the list.
Using this approach you can check if you have an Integer on any element just comparing it to Nil
, like with:
if Nil=MyStringList.Objects[MyIndex]
then begin
end
else begin
end;
And to get the integer value is as simple as:
MyInteger:=TIntegerObject(MyStringList.Objects[MyIndex]).value;
Hope this helps people to better code.
I know it is much easier to code it as just MyStringList.Objects[MyIndex]:=TObject(MyInteger);
and MyInteger:=Integer(MyStringList.Objects[MyIndex]);
, but that is like doing a FAKE/LIE, doing such you are telling MyInteger has the memory start position of an object that does not really exists; that is prone to cause a lot of errors when used as what it is, a memory pointer, such memory address may not belong to the app, such can cause errors or also something worst, code injection security holes, etc., by the way, that is very well common known to had been used to crack consoles securities, jailbreacks, etc.
Of course creating an object for each Integer is a waste of time and memory.
It is up to the coder, to use one or another (or other) approach, but remember to be very precise (now and on the future) and my recommendation is if you cast Integers as Objects (or pointers) add a comment and never ever try to free them.
Another warning: setting some properties of some objects to Nil can cause a Free, and if such 'pointer' points to a what is not an object or a memory allocated by the app, will cause an error.
Just an example of the last thing, setting a TObjectList (with OwnsObjects
property set to True
) will do a Free on each element as well as a Free on the list it self (at least on what i have tested) so doing any of this lines of code Frees the objects and the list:
Remember that MyObjectList
for this sample has OwnsObjects
property set to True
.
MyObjectList:=Nil; // This will actually free the whole list and Nil it;
MyObjectList.Free; // This will actually free the whole list but not Nil it;
You must decide what to use, I just prefer to be on the safe line, I can not know how many years in the future I will be on the need to edit the code.