Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Delphi Generics support Lower / Upper Type Bounds?

Does Delphi support lower / upper type bounds for its generics, e.g. such as Scala does?

I did not find anything about it in the Embarcadero docs:

  • Overview of Generics
  • Declaring Generics
  • Constraints in Generics

Moreover, there is an implicit hint against type bounds at "Constraints in Generics":

Constraint items include:

  • Zero, one, or multiple interface types
  • Zero or one class type
  • The reserved word "constructor", "class", or "record"

You can specify both "constructor" and "class" for a constraint. However, "record" cannot be combined with other reserved words. Multiple constraints act as an additive union ("AND" logic).

Example:

Let's look at the behavior in the following Scala code, that demonstrates the usage of an upper bound type restriction. I found that example on the net:

class Animal
class Dog extends Animal
class Puppy extends Dog

class AnimalCarer{
  def display [T <: Dog](t: T){ // Upper bound to 'Dog'
    println(t)
  }
}

object ScalaUpperBoundsTest {
  def main(args: Array[String]) {

    val animal = new Animal
    val dog = new Dog
    val puppy = new Puppy

    val animalCarer = new AnimalCarer

    //animalCarer.display(animal) // would cause a compilation error, because the highest possible type is 'Dog'.

    animalCarer.display(dog) // ok
    animalCarer.display(puppy) // ok
  }
}

Is there any way to achieve such a behavior in Delphi?

like image 337
Rene Knop Avatar asked Sep 24 '18 12:09

Rene Knop


1 Answers

In Delphi this example would look like following (stripped irrelevant code):

type
  TAnimal = class(TObject);

  TDog = class(TAnimal);

  TPuppy = class(TDog);

  TAnimalCarer = class
    procedure Display<T: TDog>(dog: T);
  end;

var
  animal: TAnimal;
  dog: TDog;
  puppy: TPuppy;
  animalCarer: TAnimalCarer;
begin
//  animalCarer.Display(animal); // [dcc32 Error] E2010 Incompatible types: 'T' and 'TAnimal'
  animalCarer.Display(dog);
  animalCarer.Display(puppy);
end.

It is not possible to specify a lower bound as shown in the article you linked to because Delphi does not support that. It also does not support any type variance.

Edit: FWIW in this case the Display method would not even have to be generic and the dog parameter could just be of type TDog as you then can pass any subtype. Because of the limited capabilities of generics in Delphi the Display method would not benefit of being generic.

like image 69
Stefan Glienke Avatar answered Nov 20 '22 11:11

Stefan Glienke