At GDK we are continuously working with cutting-edge tools and techniques. This means that we also need to keep ourselves up to date! We do this using knowledge sessions in which we discuss various subjects. Our last session was about Delphi interfaces and collections.
First of all: An interface provides a contract to talk to when we work with objects that implement it. As a result, we don’t have to worry about the implementation details of that object (from the perspective of the calling code). It’s one of the best examples of the Solid principles.
Secondly: in Delphi, we use them to prevent memory leaks by using its reference counting mechanism. If an interface runs out of scope and it was the last reference to the object it was pointing to, then it will be automatically removed.
Collections have been implemented since the beginning of Delphi. We could choose from TLists for pointers, TObjectList for objects (which can be owned by the list; very useful), TStringList etc. Although these collections are very handy, they have some limitations. When using them, you always need to cast in order to get the right datatype out of the list. This also makes the code prone to errors, because the compiler doesn’t complain if an object is cast to a different class than it really is. You only find out about it during runtime.
MyObject := TMyType(MyList);
To get around the whole casting issue and to make the code more readable the Generics Collections has been added in Delphi 2009. As a result, we can now specify the datatype that goes in the collection we use. We do this by specifying the datatype between angle brackets. Now the compiler knows what goes into the collection and the chance of casting to the wrong class is now minimized.
It is even possible to use interfaces as parameter types. This applies to all collection implementations except for the TObjectList. This class needs a type that extends from TObject.
MyList := TList<TMyType>.Create; MyList.Add(MyObject); MyOtherObject := MyList;
The best of two worlds! Now we can use our beloved interfaces together with collections and get all the benefits from using interfaces. The only thing we are still missing is the fact that the Generics Collections objects don’t implement an interface themselves.
The Spring4D framework (among other very useful classes) provides just that: lists that are referenced using interfaces. And more: because the Spring4D collection classes are built from the ground up, they provide with a lot of handy functions that are not available in the Generics Collections framework. Go check out the Spring4D documentation to find out.
MyTypedObject := TMyType.Create); MyList := TCollections.CreateList<IMyType>; MyList.Add(MyTypedObject);
By using Generics Collections in combination with interfaces we automatically make sure that our code is less prone to errors. This is because we let the compiler know what goes into the collections we use so it can check for any violations.
What we highly recommend is using the Spring4D framework for all the handy functionality it provides us when working with collections! Watch our Youtube channel for all videos on Spring4D: https://youtube.com/@GDKSoftware