【问题标题】:"Nested" type constraints in DelphiDelphi 中的“嵌套”类型约束
【发布时间】:2016-01-31 22:22:53
【问题描述】:

假设我有一堂课

TController<T_Ui: TGui; T_Man: TManager> = class
end;

如果我尝试将此类用作这样的通用过程的约束:

procedure MyProc<T: TController<T_Ui, T_Man>>(ACont: T);

我收到一个错误undefined identifier T_Ui


有没有比定义过程更短的方法

procedure MyProc<T_Ui: TGui; TMan: TManager; T: TController<T_Ui, T_Man>>(ACont: T);

如果我想要的只是对 TController 类型的约束 T?

已编辑:

如果我可以定义:

procedure MyProc<T: TController<*, *>>(ACont: T);

编译器应该清楚一切。

我的问题是,而不是写

MyProc<TMyController>(Cont);

我要写

MyProc<TMyUi, TMyManager, TMyController>(Cont);

【问题讨论】:

  • 如果您必须使用泛型,那么我认为@DavidHeffernan 的回答就足够了。但是不要忘记 type TGuiClass = class of TGui; 等类类型,您可以将其作为参数传递、存储在变量中并像通常的类型一样使用它们。
  • @Abelisto 对于我的具体问题,泛型是可行的方法,但感谢您的提示。

标签: delphi delphi-xe4


【解决方案1】:
procedure MyProc<T: TController<T_Ui, T_Man>>(ACont: T);

让我们考虑一下这意味着什么。这是一个具有一个泛型参数T 的泛型方法,这是一个必须从TController&lt;T_Ui, T_Man&gt; 派生的类。由于T_UiT_Man 不是泛型参数,编译器必须将它们解释为具体类型。您没有定义该名称的类型,因此编译器错误。

当然,您不希望编译器将T_UiT_Man 视为具体类型。您的意思是它们是通用参数。在这种情况下,您必须这样声明它们。

procedure MyProc<T_Ui: TGui; TMan: TManager; T: TController<T_Ui, T_Man>>(ACont: T);

或者像这样。

procedure MyProc<T_Ui: TGui; TMan: TManager>(ACont: TController<T_Ui, T_Man>);

通过删除冗余参数T 更简单。

本质上,您希望进行隐式参数化,但这并不存在。泛型参数必须显式声明。

现在,有时使用的一种技术是将非泛型类声明为泛型类的基类型。

type
  TController = class
    ....
  end;

  TController<T_Ui: TGui; T_Man: TManager> = class(TController)
    ....
  end;

然后你可以这样写你的泛型方法:

procedure MyProc<T: TController>(ACont: T);

现在,这种方法要求您可以在 TController 中声明足够的功能。如果MyProc 需要调用只能在从TController 派生的泛型类中声明的方法,那么这种方法对你没有用处。

【讨论】:

  • 您对错误的看法是正确的。我希望存在一些语法糖来解决这个问题。我知道有一个非泛型基类的解决方案,但这对我没有用。
  • 关于您的第二个建议。声明接口而不是类更简单通用:TController&lt;T_Ui: TGui; T_Man: TManager&gt; = class(IController) 然后procedure MyProc(ACont: IController);
  • @Abelisto 这取决于您是希望使用接口继承还是实现继承。或者甚至两者兼而有之。
  • 如果您只需要基类 TController 的功能,procedure MyProc&lt;T_Ui: TGui; TMan: TManager&gt;(ACont: TController&lt;T_Ui, T_Man&gt;); 很有用
  • 如果你指定第三个参数,你能用它做什么?您只能使用您限制的功能。无论如何,您询问了隐式参数,它们不存在。我想你知道所有要知道的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-21
  • 1970-01-01
相关资源
最近更新 更多