DELPHI: Generics and polymorphism

前端 未结 1 1633
陌清茗
陌清茗 2020-12-28 21:47

This has been asked several different ways already - but I haven\'t found my answer yet.

Can someone clarify a few things for me please. Using : Delphi XE2

I

相关标签:
1条回答
  • 2020-12-28 22:25

    Delphi generics do not support covariance and contravariance so what you are attempting to do is not possible with the language's current syntax. I suggest you have a read of the following blog articles that cover the matter in more detail.

    • Craig Stuntz: Comparing C#, C++, and Delphi (Win32) Generics
    • Mason Wheeler: Generics and the Covariance Problem

    Fundamentally what you are attempting to do is this:

    type
      TBase = class;
      TDerived = class(TBase);
      TBaseList = TList<TBase>;
      TDerivedList = TList<TDerived>;
    var
      BaseList: TBaseList;
      DerivedList: TDerivedList;
    ...
    BaseList := TDerivedList;//does not compile
    

    The designers have not stopped you doing this out of spite. There is a good reason. Consider the following standard example:

    type
      TAnimal = class;
      TCat = class(TAnimal);
      TPenguin = class(TAnimal);
    
    var
      AnimalList: TList<TAnimal>;
      CatList: TList<TCat>;
      Penguin: TPenguin;
    ...
    AnimalList := CatList;//does not compile because...
    AnimalList.Add(Penguin);//...of the danger of this
    

    Whilst it is reasonable to add a TPenguin to a TList<TAnimal>, the actual list that AnimalList refers to is a TList<TCat> and a penguin is not a cat.

    And, if you want to think of it in the context of your example hierarchy, here's an illustration of code that justifies the language design.

    aList := aCustomerList;//does not compile
    aList.Add(aCustomPerson);
    //this would add a TCustomPerson instance to a list containing 
    //TCustomer instances, but a TCustomPerson is not a TCustomer
    
    0 讨论(0)
提交回复
热议问题