Delphi通用约束问题 [英] Delphi Generic constraints problem
问题描述
我正在尝试创建一个通用列表类,以便与tiOPF一起使用(delphi @ www.tiopf.com的对象持久化框架)。具体来说,我正在尝试使用现有的泛型类(TtiObjectList)并制作一个使用TtiObject降级的泛型版本。
我修改基本类的范围有限,因为它们需要在D7 - D2009和Free Pascal下编译。我需要从TtiObjectList下降,以保持现有的持久性机制。
//基类
类型
TtiObjectList = class(TtiObject)
...
protected
函数GetItems(i:integer):TtiObject;虚拟;
过程SetItems(i:integer; const AValue:TtiObject);虚拟;
...
public
函数Add(const AObject:TtiObject):integer;超载;虚拟;
...
end;
我的课程定义如下:
TtiGenericObjectList< T:TtiObject> = class(TtiObjectList)
protected
函数GetItems(i:integer):T;重新引入;
过程SetItems(i:integer; const Value:T);重新引入;
public
函数Add(const AObject:T):integer;重新引入;
属性Items [i:integer]:T读取GetItems写入SetItems;默认;
end;
实现
{TtiGenericObjectList< T> }
函数TtiGenericObjectList< T> .Add(const AObject:T):integer;
var obj:TtiObject;
begin
obj:= TtiObject(AObject); ///无效的类型转换
result:= inherited Add(obj);
end;
// alternate add,也失败
函数TtiGenericObjectList< T> .Add(const AObject:T):integer;
begin
result:= inherited Add(AObject); /// **没有重载版本**
/// **可以用这些参数调用的'Add'**
end;
函数TtiGenericObjectList< T> .GetItems(i:integer):T;
begin
result:= T(继承GetItems(i)); /// **无效的类型转换**
end;
procedure TtiGenericObjectList< T> .SetItems(i:integer; const Value:T);
begin
继承SetItems(i,Value);
end;
我遇到的问题是delphi没有将T看作TtiObject的后代。当我做类似以下操作时,我遇到了无效的类型转换错误:
pre $函数TtiGenericObjectList<整数;
var obj:TtiObject;
begin
obj:= TtiObject(AObject); /// **无效的类型转换***
result:= inherited Add(obj);
end;
如果我没有进行类型转换,则会出现重载错误以上。
任何想法我错了?
肖恩
<它看起来像问题不是我,但编译器:)。
最后,我使用以下方法对它进行了破解。
类函数TtiGenericObjectList< T> .GenericAsObject(const Value):TObject;
begin
结果:= TObject(Value);
end;
类函数TtiGenericObjectList< T> ;.ObjectAsGeneric(const Value):T;
begin
结果:= T(Value);
end;
用法如下
函数TtiGenericObjectList< T> .Add(const AObject:T):integer;
var obj:TtiObject;
begin
obj:= TtiObject(GenericAsObject(AObject));
结果:=继承添加(obj);
//替换出现以下错误:
// result:= inherited Add(TtiObject(AObject));
end;
和
function TtiGenericObjectList< T> .GetItems(i:integer):T;
var obj:TtiObject;
begin
obj:=继承GetItems(i);
结果:= ObjectAsGeneric(obj);
//替换下面的Invalid typecast错误
// result:= inherited Add(AObject);
end;
我会清理这些东西,并在编译器修复之前使用它们。 b $ b
I am trying to create a generic list class for use with tiOPF (an Object Persistence Framework for delphi @ www.tiopf.com). Specifically I am trying to take an existing generic class (TtiObjectList) and make a generic version that uses TtiObject descenants.
I have limited scope for altering the base classes as they need to compile under D7 - D2009 and Free Pascal. I need to descend from TtiObjectList to keep the existing persistence mechanisms working.
// 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;
My class is defined as follows:
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;
The problem I have is that delphi is not seeing T as a TtiObject descendant. I am getting invalid typecast errors when I do something like:
function TtiGenericObjectList<T>.Add(const AObject: T): integer;
var obj: TtiObject;
begin
obj:= TtiObject(AObject); /// **Invalid typecast***
result:= inherited Add(obj);
end;
If I don't do a type cast, then I get overload errors instead as shown in the listing above.
Any ideas where I am going wrong?
Sean
It looks like the problem is not me, but the compiler :).
In the end, I have hacked around it using the following methods
class function TtiGenericObjectList<T>.GenericAsObject(const Value): TObject;
begin
Result := TObject(Value);
end;
class function TtiGenericObjectList<T>.ObjectAsGeneric(const Value): T;
begin
Result := T(Value);
end;
used as follows
function TtiGenericObjectList<T>.Add(const AObject: T): integer;
var obj: TtiObject;
begin
obj:= TtiObject(GenericAsObject(AObject));
result:= inherited Add(obj);
// replaces the following which gets overload errors
// result:= inherited Add(TtiObject(AObject));
end;
and
function TtiGenericObjectList<T>.GetItems(i: integer): T;
var obj: TtiObject;
begin
obj:= inherited GetItems(i);
result:= ObjectAsGeneric(obj);
// replaces the following which gets "Invalid typecast" errors
// result:= inherited Add(AObject);
end;
I will clean these up a bit and use them till the compiler gets fixed.
这篇关于Delphi通用约束问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!