i added map(), reduce() and where(qlint : string) to a Spring4D fork of mine. While i was programming these functions, i found out that there is a differnce in the behaviour of the lists, when they are created in different ways.
If i create them with TList<TSomeClass>.create
the objects in the enumerables are of the type TSomeClass
.
If i create them with TCollections.CreateList<TSomeClass>
the objects in the enumerables are of the type TObject
.
So the question is:
Is there a downside by using TList<TSomeClass>.create
?
Or in other words: Why should i use TCollections.CreateList<TSomeClass>
?
btw: with TCollections.CreateList i got a TObjectList and not a TList. So it should be called TCollections.CreateObjectList... but that's another story.
Depending on the compiler version many of the Spring.Collections.TCollections.Create
methods are applying what the compiler is unable to: folding the implementation into only a very slim generic class. Some methods are doing that from XE on, some only since XE7 ( GetTypeKind
intrinsic function makes it possible to do the type resolution at compile time - see the parameterless TCollections.CreateList<T>
for example).
This greatly reduces the binary size if you are creating many different types of IList<T>
(where T are classes or interfaces) because it folds them into TFolded(Object|Interface)List<T>
. However via the interface you are accessing the items as what you specified them and also the ElementType
property returns the correct type and not only TObject
or IInterface
. On Berlin it adds less than 1K for every different object list while it would add around 80K if the folding is not applied due to all the internal classes involved for the different operations you can call on an IList<T>
.
As for TCollections.CreateList<T>
returning an IList<T>
that is backed by a TFoldedObjectList<T>
when T is a class that is completely as designed. Since the OwnsObject
was passed as False
it has the exact same behavior as a TList<T>
.
The Spring4D collections are interface based so it does not matter what class is behind an interface as long as it behaves accordingly to the contract of the interface.
Make sure that you only carry the lists around as IList<T>
and not TList<T>
- you can create them both ways (with the benefits I mentioned before when using the TCollections
methods). In our own application some places are still using the constructor of the classes while many other places are using the static methods from Spring.Collections.TCollections
.
BTW:
I saw the activity in your fork and imo there is no need to implement Map/Reduce because that is already there. Since the Spring4D collections are modelled after .NET they are called Select
and Aggregate
(see Spring.Collections.TEnumerable
). They are not available on IEnumerable<T>
directly though because interfaces must not have generic parameterized methods.