我正在检查Delphi 2009试用版,但是立即遇到了仿制药问题。
下面的代码没有编译,我一点也不知道为什么它给了我E2015的Equals()方法:
type
TPrimaryKey<T> = class(TObject)
strict private
fValue: T;
public
constructor Create(AValue: T);
function Equals(Obj: TObject): boolean; override;
function GetValue: T;
end;
constructor TPrimaryKey<T>.Create(AValue: T);
begin
inherited Create;
fValue := AValue;
end;
function TPrimaryKey<T>.Equals(Obj: TObject): boolean;
begin
Result := (Obj <> nil) and (Obj is TPrimaryKey<T>)
and (TPrimaryKey<T>(Obj).GetValue = fValue);
end;
function TPrimaryKey<T>.GetValue: T;
begin
Result := fValue;
end;
为什么编译器认为无法比较fValue和GetValue()的结果?
答案 0 :(得分:6)
如果T是一个字符串怎么办?如果它是TSize记录怎么办?
不限制T(例如,使用&lt; T:class&gt;),您无法确定比较是否有意义。
相反,如果要比较T类型的两个值,可以使用Generics.Defaults单元并使用:
TEqualityComparer<T>.Default.Equals(x, y)
比较T类型的值x和y。
答案 1 :(得分:3)
答案 2 :(得分:2)
我认为原始海报试图围绕简单类型(整数,双等等)创建一个对象包装器,因此将T限制为类可能不适用于他想要的东西。
答案 3 :(得分:1)
编译器无法确定两个“T”是否相同。但是通过一个小技巧,你可以使它工作:
type
TPrimaryKey<T> = class(TObject)
public
type
TCompare<T1> = reference to function(const A1, A2: TPrimaryKey<T1>): Boolean;
private
fValue: T;
fCompare : TCompare<T>;
public
constructor Create(AValue: T; ACompare: TCompare<T>);
function Equals(Obj: TPrimaryKey<T>): Boolean; reintroduce;
function GetValue: T;
function CreateNew(const AValue: T): TPrimaryKey<T>;
end;
constructor TPrimaryKey<T>.Create(AValue: T; ACompare: TCompare<T>);
begin
inherited Create;
fValue := AValue;
fCompare := ACompare;
end;
function TPrimaryKey<T>.Equals(Obj: TPrimaryKey<T>): Boolean;
begin
Result := FCompare(self, Obj);
end;
function TPrimaryKey<T>.GetValue: T;
begin
Result := fValue;
end;
function TPrimaryKey<T>.CreateNew(const AValue: T): TPrimaryKey<T>;
begin
Result := TPrimaryKey<T>.Create(AValue, FCompare);
end;
使用以下方法对其进行实例化:
var
p1, p2 : TPrimaryKey<Integer>;
begin
p1 := TPrimaryKey<Integer>.Create(10,
function(const A1, A2: TPrimaryKey<Integer>): Boolean
begin
Result := (A1<>nil) and (A2<>nil) and (A1.GetValue=A2.GetValue);
end);
p2 := p1.CreateNew(10);
p1.Equals(p2);
end;