gpt4 book ai didi

delphi - 如何在派生类型中使用泛型方法

转载 作者:行者123 更新时间:2023-12-03 14:50:47 25 4
gpt4 key购买 nike

这看起来相当简单,也许我只是缺少一些语法粘合...这是我的简单通用(Delphi XE3)示例:

unit Unit1;

interface

uses
generics.collections;

type

X = class
public
Id: Integer;
end;

XList<T : X> = class( TObjectList<T> )
function Find(Id: Integer) : T;
end;

Y = class(X)

end;

YList = class(XList<Y>)
end;

implementation

{ XList<T> }

function XList<T>.Find(Id: Integer): T;
var
t: X;
begin
for t in Self do
if t.Id = Id then
Result := t;
end;

end.

这不会与“[dcc32 Error] Unit1.pas(41): E2010 不兼容类型:‘Y’和‘X’”一起编译。如下:

YList = class(XList<Y>)
end;

Y 源自 X,那么为什么会出现问题?

最佳答案

亚历克斯的回答是问题的正确解决方案。一旦知道答案就从函数返回也很好。

我想通过更多解释来扩展答案。我特别想回答您在 Alex 的回答的评论中提出的问题:

As an aside ... why doesn't the original work? T is derived from X.

问题代码在这里:

function XList<T>.Find(Id: Integer): T;
var
t: X;
begin
for t in Self do
if t.Id = Id then
Result := t;
end;

考虑泛型的方法是想象当您实例化类型并提供具体类型参数时代码是什么样子的。在本例中,我们将 T 替换为 Y。那么代码如下所示:

function XList_Y.Find(Id: Integer): Y;
var
t: X;
begin
for t in Self do
if t.Id = Id then
Result := t;
end;

现在分配给 Result 的行出现问题:

Result := t;

嗯,Result 的类型为 Y,但 t 的类型为 XXY 之间的关系是 Y 派生于 X。因此 Y 的实例是 X。但X 的实例不是Y。因此该分配无效。

正如 Alex 正确指出的那样,您需要将循环变量声明为 T 类型。就我个人而言,我会编写这样的代码:

function XList<T>.Find(Id: Integer): T;
begin
for Result in Self do
if Result.Id = Id then
exit;
Result := nil;
// or perhaps you wish to raise an exception if the item cannot be found
end;

这还解决了搜索例程在未找到项目时未初始化其返回值的问题。一旦您获得实际编译的代码,编译器就会警告这个问题。我确实希望您启用编译器警告,并在出现警告时进行处理!

关于delphi - 如何在派生类型中使用泛型方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19515573/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com