views:

129

answers:

2

Given a generic type

TMyClass <T> = class
  ...
end;

is there a way to put multiple instances (instantiated with different types) together like

FList : TList <TMyClass>;
FList.Add (TMyClass <Integer>.Create);
FList.Add (TMyClass <String>.Create);

or

FArray : array [0..1] of TMyClass;
FArray [0] := TMyClass <Integer>.Create;
FArray [1] := TMyClass <String>.Create;

I know that this code does not compile. But is it possible to achieve something like that?

+1  A: 

One option is to have a non-generic base class for TMyClass containing all the bits which don't refer to T in. You then create a TList<TMyNonGenericBaseClass> and add the instances to that. Of course you then don't know what the full concrete type is when you get them out again, but that may not be an issue for you.

Jon Skeet
Unfortunately it is an issue, because some of the methods I want to call on the objects stored in the list, use the generic type parameter :(
Smasher
So how would you expect to know what that type parameter was if you could have added different things to the list? If you *do* know it, you can just cast. If you don't know it, it wouldn't have helped...
Jon Skeet
hmm...that's right...seems that I have two go for the cast. Sad news, because I just reimplemented that part of my application to make it more beautiful ;)
Smasher
+3  A: 

You can do that if you create FList with the ancestor of TMyClass.

Generics are not inheritance so TMyClass is not the ancestor of TMyClass.

TMyAbstractClass = class
TMyClass <T> = class (TMyAbstractClass)
  ...
end;

FList : TList <TMyAbstractClass>;
FList.Add (TMyClass <Integer>.Create);
FList.Add (TMyClass <String>.Create);

FArray : array [0..1] of TMyAbstractClass;
FArray [0] := TMyClass <Integer>.Create;
FArray [1] := TMyClass <String>.Create;
Gamecat
you could use a non-generic TObjectList. You'd have to cast after retrieving the object but it would work. That's how you did it with delphi 2006 where you did not have any generics. With generics you could try TList<TObject> - that should work as well.
Tobias Langner
Thanks, Gamecat! But how can I specify the interface of TMyAbstractClass without the generic type. If I don't do that I can't take an element of the list and apply one of the methods from the interface without casting.
Smasher
I'm afraid you can't do without the cast. Just like any other list of type.
Gamecat
yes, you're right :(
Smasher
Can you tell that to my wife ;-).
Gamecat