"Nested" 在 Delphi 中键入约束
"Nested" type constraints in Delphi
假设我有一个 class
TController<T_Ui: TGui; T_Man: TManager> = class
end;
如果我尝试使用此 class 作为通用过程的约束:
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);
procedure MyProc<T: TController<T_Ui, T_Man>>(ACont: T);
让我们考虑一下这意味着什么。这是一个具有一个泛型参数 T
的泛型方法,它是一个必须从 TController<T_Ui, T_Man>
派生的 class。由于 T_Ui
和 T_Man
不是泛型参数,编译器必须将它们解释为具体类型。您没有定义该名称的类型,因此出现编译器错误。
但是您当然不希望编译器将 T_Ui
和 T_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
更简单。
本质上,您希望隐式参数化,但这并不存在。必须显式声明通用参数。
现在,有时使用的一种技术是将非泛型 class 声明为泛型 class 的基类型。
type
TController = class
....
end;
TController<T_Ui: TGui; T_Man: TManager> = class(TController)
....
end;
然后你可以这样写你的泛型方法:
procedure MyProc<T: TController>(ACont: T);
现在,这种方法要求您可以在 TController
中声明足够的功能。如果 MyProc
需要调用只能在派生自 TController
的泛型 class 中声明的方法,那么这种方法对您没有用。
假设我有一个 class
TController<T_Ui: TGui; T_Man: TManager> = class
end;
如果我尝试使用此 class 作为通用过程的约束:
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);
procedure MyProc<T: TController<T_Ui, T_Man>>(ACont: T);
让我们考虑一下这意味着什么。这是一个具有一个泛型参数 T
的泛型方法,它是一个必须从 TController<T_Ui, T_Man>
派生的 class。由于 T_Ui
和 T_Man
不是泛型参数,编译器必须将它们解释为具体类型。您没有定义该名称的类型,因此出现编译器错误。
但是您当然不希望编译器将 T_Ui
和 T_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
更简单。
本质上,您希望隐式参数化,但这并不存在。必须显式声明通用参数。
现在,有时使用的一种技术是将非泛型 class 声明为泛型 class 的基类型。
type
TController = class
....
end;
TController<T_Ui: TGui; T_Man: TManager> = class(TController)
....
end;
然后你可以这样写你的泛型方法:
procedure MyProc<T: TController>(ACont: T);
现在,这种方法要求您可以在 TController
中声明足够的功能。如果 MyProc
需要调用只能在派生自 TController
的泛型 class 中声明的方法,那么这种方法对您没有用。