这是我other question的后续行动。
当我第一次听到泛型时,就是在Delphi 2009发布之前(他们首先介绍了它)。我知道它之前在.Net中得到了支持,但我还没有挖掘那个领域。
阅读泛型,我了解到它允许类有一个变量参数,并且传递给它的任何值都将被替换为类的所有代码。
根据以下声明,描述了泛型的方式(或至少,我理解的泛型所允许的):
procedure TMyClass<T>.Init;
begin
FField := T.Create(nil);
end;
我认为它会起作用。我假设编译失败的地方如下:
begin
TMyClass<TComponent>.Create; //Works correctly
TMyClass<TObject>.Create; //Doesn't work, as even though it HAS a constructor, it has none that receive a single pointer parameter
TMyClass<string>.Create; //Doesn't work, not an object.
end;
现在,我知道我错了。所以,我现在想知道,是否有支持这种结构的技术/语言功能。代码模板也许?其他编程语言中的泛型?或者别的什么?
答案 0 :(得分:1)
现在,我知道我错了。所以呢 我现在想知道,有没有 技术/语言功能 支持这样的结构。码 模板也许?其他的泛型 编程语言?或者可能 别的什么?
C#中的泛型具有您想要的强大功能。 C ++中的模板更强大 - 通过模板生成的代码与手工编写的代码相同,除了它们只能内联编译的部分,这很糟糕。
答案 1 :(得分:1)
@Gamecat,您不能将TObject
作为约束,但您可以将class
作为约束(这可以解决缺少TObject
约束的问题。)
请注意,无论您使用的是TObject
还是class
,都无法通过参数调用Create
而无需技巧。
示例1:class
约束:
unit Unit1;
interface
uses
Classes;
type
TMyClass<T: class, constructor> = class
strict private
FField: T;
public
procedure Init;
end;
implementation
procedure TMyClass<T>.Init;
begin
FField := T.Create();
end;
end.
示例2:TComponent
作为约束,Create
unit Unit2;
interface
uses
Classes;
type
TMyClass<T: TComponent, constructor> = class
strict private
FField: T;
public
procedure Init;
end;
implementation
procedure TMyClass<T>.Init;
var
ComponentClass: TComponentClass;
begin
ComponentClass := T;
FField := ComponentClass.Create(nil);
end;
end.
除class
约束外,您还可以拥有记录约束。
有了这个,您需要Default
来初始化字段:
unit Unit3;
interface
uses
Classes;
type
TMyClass<T: record> = class
strict private
FField: T;
public
procedure Init;
end;
implementation
procedure TMyClass<T>.Init;
begin
FField := Default(T);
end;
end.
希望能够对泛型和约束有所了解。
- 的Jeroen
答案 2 :(得分:0)
您可以将约束放在泛型类型上。如果要使用该类型的某些方面,则需要此选项。例如,一种方法。
如果要调用构造函数,则需要在类约束旁边给出consructor约束:
type
TMyClass<T: TComponent, constructor> = class
// ..
end;
procedure TMyClass<T>.Init;
begin
FField := T.Create(nil);
end;
不幸的是,TObject不是有效的约束。 (根据Delphi XE)。
现在,我知道我错了。所以,我现在想知道,是否有支持这种结构的技术/语言&gt;功能。代码模板也许?其他&gt;编程语言中的泛型?或者别的什么? 这可能有风险甚至毫无意义。如果在泛型上调用方法X并使用不支持方法X的类对其进行实例化,那么正确的行为是什么......
答案 3 :(得分:0)
@Ken:为了让你所要求的代码以真正的通用方式工作,你需要有一个统一的输入系统,它可以合并引用类型(类)和值类型(字符串,整数等)。 / p>
从历史上看,原生Delphi没有这样的打字系统(.NET有,Delphi Prism中的泛型支持它,就像C#和VB.NET一样)。
解决这个问题很困难; Allen Bauer gave it a shot implementing a Nullable type,他必须做一些严格的扭曲,以覆盖引用和值类型的方式仅实现Equals(=)和NotEquals(&lt;&gt;)运算符行为。
所以支持这些将是艰难的,但可能是可行的:
begin
TMyClass<TComponent>.Create; //Works correctly
TMyClass<TObject>.Create; //Doesn't work, as even though it HAS a constructor, it has none that receive a single pointer parameter
TMyClass<string>.Create; //Doesn't work, not an object.
end;
- 的Jeroen