"as" 和 "is" 不适用于泛型
"as" and "is" are not applicable to generic type
我很惊讶泛型不受 "is" 和 "as" 操作的约束。
如何实现以下内容?:
function TDisplayConfManager._getDisplay<T>(parentCtl: TWinControl; indicatorName: string): T;
var
i: Integer;
ind: T;
begin
for i := 0 to parentCtl.ControlCount-1 do
if parentCtl.Controls[i] is T then begin // E2015 Operator not applicable to this operand type
ind := parentCtl.Controls[i] as T; // E2015 Operator not applicable to this operand type
if SameText(ind.Caption, indicatorName) then Exit(ind); // E2003 Undeclared identifier: 'Caption'
end;
Result := T.Create(_owner); // E2003 Undeclared identifier: 'Create'
end;
如果我对所有显示使用基本显示 class,两个错误就会消失,但我仍然不能使用 "is" 并创建一个对象:
function TDisplayConfManager._getDisplay<T>(parentCtl: TWinControl; indicatorName: string): T;
var
i: Integer;
ind: TBaseDisplayType;
begin
for i := 0 to parentCtl.ControlCount-1 do
if parentCtl.Controls[i] is T then begin // E2015 Operator not applicable to this operand type
ind := parentCtl.Controls[i] as TBaseDisplayType;
if SameText(ind.Caption, indicatorName) then Exit(ind);
end;
Result := T.Create(_owner); // E2003 Undeclared identifier: 'Create'
end;
原因是T
不需要是class类型;它也可以是 non-class 类型,例如整数、字符串、记录或数组。
因此以下内容无法编译:
type
TTest<T> = record
function Test(AObject: TObject): Boolean;
end;
{ TTest<T> }
function TTest<T>.Test(AObject: TObject): Boolean;
begin
Result := AObject is T; // E2015 Operator not applicable to this operand type
end;
但是,如果您知道您的 T
类型将始终是 class 类型,您可以在 Delphi:
中表示
type
TTest<T: class> = record
function Test(AObject: TObject): Boolean;
end;
{ TTest<T> }
function TTest<T>.Test(AObject: TObject): Boolean;
begin
Result := AObject is T;
end;
documentation 包含有关通用约束的更多详细信息。
更新回复评论:
您还可以在成员级别设置约束:
type
TTest = record
function Test<T: class>(AObject: TObject): Boolean;
end;
{ TTest }
function TTest.Test<T>(AObject: TObject): Boolean;
begin
Result := AObject is T;
end;
我很惊讶泛型不受 "is" 和 "as" 操作的约束。
如何实现以下内容?:
function TDisplayConfManager._getDisplay<T>(parentCtl: TWinControl; indicatorName: string): T;
var
i: Integer;
ind: T;
begin
for i := 0 to parentCtl.ControlCount-1 do
if parentCtl.Controls[i] is T then begin // E2015 Operator not applicable to this operand type
ind := parentCtl.Controls[i] as T; // E2015 Operator not applicable to this operand type
if SameText(ind.Caption, indicatorName) then Exit(ind); // E2003 Undeclared identifier: 'Caption'
end;
Result := T.Create(_owner); // E2003 Undeclared identifier: 'Create'
end;
如果我对所有显示使用基本显示 class,两个错误就会消失,但我仍然不能使用 "is" 并创建一个对象:
function TDisplayConfManager._getDisplay<T>(parentCtl: TWinControl; indicatorName: string): T;
var
i: Integer;
ind: TBaseDisplayType;
begin
for i := 0 to parentCtl.ControlCount-1 do
if parentCtl.Controls[i] is T then begin // E2015 Operator not applicable to this operand type
ind := parentCtl.Controls[i] as TBaseDisplayType;
if SameText(ind.Caption, indicatorName) then Exit(ind);
end;
Result := T.Create(_owner); // E2003 Undeclared identifier: 'Create'
end;
原因是T
不需要是class类型;它也可以是 non-class 类型,例如整数、字符串、记录或数组。
因此以下内容无法编译:
type
TTest<T> = record
function Test(AObject: TObject): Boolean;
end;
{ TTest<T> }
function TTest<T>.Test(AObject: TObject): Boolean;
begin
Result := AObject is T; // E2015 Operator not applicable to this operand type
end;
但是,如果您知道您的 T
类型将始终是 class 类型,您可以在 Delphi:
type
TTest<T: class> = record
function Test(AObject: TObject): Boolean;
end;
{ TTest<T> }
function TTest<T>.Test(AObject: TObject): Boolean;
begin
Result := AObject is T;
end;
documentation 包含有关通用约束的更多详细信息。
更新回复评论:
您还可以在成员级别设置约束:
type
TTest = record
function Test<T: class>(AObject: TObject): Boolean;
end;
{ TTest }
function TTest.Test<T>(AObject: TObject): Boolean;
begin
Result := AObject is T;
end;