views:

171

answers:

2

Is it possible to constrain the type of generic to, say, two different classes?

Like so:

TSomeClass<T: FirstClass; T: SecondClass> = class
  // ...
end;

(Sorry about the lack of formatting - the SO tool bar has disappeared from my browser). I know the above won't compile, its only written so to give you guys an idea. I tried

TSomeClass<T: FirstClass, SecondClass> = class
  // ...
end;

but then I wasn't allowed to write

procedure TSomeClass.SomeMethod<T> (Param1: string);

Is this even possible?

+9  A: 

No, it's not possible. How should the compiler be able to statically verify that your method calls are valid?

Note, that

TSomeClass <T : FirstClass, SecondClass>

is not a valid type constraint. You cannot combine multiple class constraints. You can combine a class constraint with some interface constraints though. But even then

TSomeClass <T : TSomeClass, ISomeInterface>

means, that the generic type has to descend from TSomeClass and implement ISomeInterface.

So the only thing you can do is to extract the stuff that is common between FirstClass and SecondClass, put it in an interface and use an interface constraint:

TSomeClass <T : IOnePointFive>

Perhaps you can give some more details about what you want to achieve.

Smasher
+1 for the name of the interface :)
Tihauan
Thanks Smasher. To me, generics seems like magic anyway, so I have no intuition of what the compiler may be able to catch or not... But having them implement the same interface is an acceptable solution. Actually, I solved my problem by using class methods instead: turned out that what differs between my classes are class wide differences. With class methods I don't need an instance of the class to make us of it, and thus worked around it.
conciliator
+2  A: 

Having both classes implement the same interface is the way to go. Then constrain the generic to that interface.

Jim McKeeth
Thanks Jim. I wish I could've accepted both yours and Smasher's answer, but I've got to with Smasher's since he was first, and due to the level of detail in his post. But thanks for the effort!
conciliator