0

I have a class MyClass, which is not generic and contains and does something with an arbitrary TList. I wish to replace the TList with the generic TList, but MyClass has to stay non-generic. Since Delphi is invariant something like this doesn't work:

list1: TList<TObject>
list2: TList<MyType> //MyType extends TObject
[...]
list1 := list2

Furthermore there seems to be no non-generic Superclass of TList, just IEnumerable.

Is there a way to declare a placeholder/wildcard for TList with an arbitrary T?

Kiwi
  • 73
  • 7

2 Answers2

4

This is a problem of missing support for Co- and Contravariance in Delphi. However if you know that you are just doing operations that are covariant (i.e. iterating the elements in the list) you can just hardcast your TList<MyType> to TList<TObject> given that MyType inherits from TObject.

Taking the example from the Wikipedia article you can handle a list of cats like a list of animals when you are just looping through and reading their names or something.

But you have to be careful with actions that need contravariance (i.e. adding elements).

Again the example you cannot put a dog into the list of animals because actually the list is a list of cats.

Stefan Glienke
  • 20,860
  • 2
  • 48
  • 102
  • 2
    These hard casts are usually a bad idea. A naive reader of the answer might infer that you are endorsing such casts as being a good idea. – David Heffernan Mar 14 '14 at 13:09
  • 1
    Propably the best solution for now, although I don't like the casting. – Kiwi Mar 14 '14 at 13:13
  • Why do you think this is the best solution? I doubt it is. I would not suggest a solution without knowledge of what the problem is. – David Heffernan Mar 14 '14 at 13:31
  • 2
    A hardcast is legit. The more complicated question is are you only doing covariant things with list1 after (which you can not ensure). This is something that .NET solves with IReadOnlyList which is covariant (while IList is not) because it does not allow manipulation of the list. Spring4D has these. – Stefan Glienke Mar 14 '14 at 14:13
  • The Problem occured in an existing Project, which was developed over the last ~18 years. MyClass is actually an overriden VCL StringGrid with arround 10k additional lines of code and gets fed Lists extending TList, each with its own purpose and methods. I was tasked with changing TList to a generic List – Kiwi Mar 14 '14 at 14:26
0

The answer is no, this cannot be done. You cannot include in non-generic class, an object of a non-instantiated generic type.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490