代码之家  ›  专栏  ›  技术社区  ›  Vegar

Delphi:泛型子体的泛型列表,并将泛型作为参数

  •  3
  • Vegar  · 技术社区  · 15 年前

    我在理解泛型以及它们如何可以和不可以被使用方面有些困难。

    我有一个通用类TControlMediator,如下所示:

    TControlMediator<C, T> = class
    private
      FMediatedComponent: C;
    public
      constructor Create(ComponentToMediate: C);
    
      function GetValue: T; virtual; abstract;
      procedure SetValue(Value: T); virtual; abstract;
    
      property MediatedControl: C read FMediatedComponent;
    end;
    

    TEditMediator = class(TControlMediator<TEdit, string>)
    public
      function GetValue: string; override;
      procedure SetValue(Value: string); override;
    end;
    

    到目前为止,一切似乎都正常。但是,当我需要TControlMediator子体列表或将TControlMediator作为方法的参数时,会出现问题:

    TViewMediator = class
    private
      FControlMediators: TList<TControlMEdiator<C, T>>;
    public
      procedure registerMediator(AControlMediator: TControlMediator<C, T>);
      procedure unregisterMediator(AControlMediator: TControlMediator<C, T>);
    end;
    

    编译器因出现致命错误而停止:

    [DCC Error] mediator.pas(23): E2003 Undeclared identifier: 'C'
    [DCC Error] mediator.pas(28): E2007 Constant or type identifier expected
    

    1 回复  |  直到 15 年前
        1
  •  6
  •   Craig Stuntz    15 年前

    Delphi在其泛型类型上没有协变或逆变。泛型类型必须使用实际类型作为参数。换言之,这:

    TViewMediator = class
    private
      FControlMediators: TList<TControlMEdiator<C, T>>;
    public
      procedure registerMediator(AControlMediator: TControlMediator<C, T>);
      procedure unregisterMediator(AControlMediator: TControlMediator<C, T>);
    end;
    

    …将不起作用,因为C和t不是 TViewMediator 或实际类型。

    TControlMediator<TEdit, string> 是一种类型。 TList<TControlMEdiator<C, T>> C T 实例化