我正在尝试创建一个与 tiOPF (delphi @ www.tiopf.com 的对象持久框架)一起使用的通用列表类。具体来说,我试图采用现有的泛型类 (TtiObjectList) 并制作一个使用 TtiObject 后代的泛型版本。
我更改基类的范围有限,因为它们需要在 D7 - D2009 和 Free Pascal 下编译。我需要从 TtiObjectList 下降以保持现有的持久性机制正常工作。
// base class
type
TtiObjectList = class(TtiObject)
...
protected
function GetItems(i: integer): TtiObject; virtual;
procedure SetItems(i: integer; const AValue: TtiObject); virtual;
...
public
function Add(const AObject : TtiObject): integer; overload; virtual;
...
end;
我的类定义如下:
TtiGenericObjectList<T: TtiObject> = class(TtiObjectList)
protected
function GetItems(i:integer): T; reintroduce;
procedure SetItems(i:integer; const Value: T); reintroduce;
public
function Add(const AObject: T): integer; reintroduce;
property Items[i:integer]: T read GetItems write SetItems; default;
end;
implementation
{ TtiGenericObjectList<T> }
function TtiGenericObjectList<T>.Add(const AObject: T): integer;
var obj: TtiObject;
begin
obj:= TtiObject(AObject); /// Invalid typecast
result:= inherited Add(obj);
end;
// alternate add, also fails
function TtiGenericObjectList<T>.Add(const AObject: T): integer;
begin
result:= inherited Add(AObject); /// **There is no overloaded version**
/// **of 'Add' that can be called with these arguments**
end;
function TtiGenericObjectList<T>.GetItems(i: integer): T;
begin
result:= T(inherited GetItems(i)); /// **Invalid typecast **
end;
procedure TtiGenericObjectList<T>.SetItems(i: integer; const Value: T);
begin
inherited SetItems(i, Value);
end;
我遇到的问题是 delphi 没有将 T 视为 TtiObject 后代。当我执行以下操作时,我收到无效的类型转换错误:
function TtiGenericObjectList<T>.Add(const AObject: T): integer;
var obj: TtiObject;
begin
obj:= TtiObject(AObject); /// **Invalid typecast***
result:= inherited Add(obj);
end;
如果我不进行类型转换,则会出现重载错误,如上面的列表所示。
有什么想法我哪里出错了吗?
Sean
Delphi 2009 编译器在其泛型实现中存在一些非常严重的缺陷。它几乎不理解约束的含义,(Barry Kelly 在 SO 的其他地方承认了这一点;我不记得确切的位置,)并且跨单元泛型可能会导致非常奇怪的问题。最好的办法是根据具体情况来处理这个问题:如果您的代码可以编译,请使用它。如果没有,请返回非通用实现,直到他们修复它。希望我们能在不久的将来看到修复泛型(和 Generics.Collections 单元)的更新。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)