基本上,我希望一个类能够实现同一个通用接口的两个不同版本。
考虑这段代码
type
// a generic interface
ITest<T> = interface
['{6901FE04-8FCC-4181-9E92-85B73264B5DA}']
function Val: T;
end;
// a class that purports to implement two different types of that interface
TTest<T1, T2> = class(TInterfacedObject, ITest<T1>, ITest<T2>)
protected
fV1: T1;
fV2: T2;
public
constructor Create(aV1: T1; aV2: T2);
function Val: T1; // Val() for ITest<T1>
function T2Val: T2; // Val() for ITest<T2>
function ITest<T2>.Val = T2Val; // mapping
end;
constructor TTest<T1, T2>.Create(aV1: T1; aV2: T2);
begin
inherited Create;
fV1 := aV1;
fV2 := aV2;
end;
function TTest<T1, T2>.T2Val: T2;
begin
result := fV2;
end;
function TTest<T1, T2>.Val: T1;
begin
result := fV1;
end;
/////////////
procedure Test;
var
t : TTest<integer, string>;
begin
t := TTest<integer, string>.Create(39, 'Blah');
ShowMessage((t as ITest<string>).Val); // this works as expected
ShowMessage(IntToStr((t as ITest<integer>).Val)); // this gets AV
end;
如我所料,第一个 ShowMessage 显示“Blah”,但第二个崩溃。它崩溃的原因是因为调用调用 T2Val() 而不是 Val() 正如我所期望的那样。显然,冲突解决映射映射了两种类型的接口的方法,而不仅仅是 ITest: T2。
所以,这是我的问题。
这是一个错误吗?我的意思是,Embarcadero 是否打算支持这一点并且只是错误地实施它?还是他们根本就没有打算让程序员做这样的事情?(老实说,我的测试程序竟然编译了,我有点惊讶)
如果这是一个错误,是否有人知道是否有一种解决方法可以让我让一个类支持两种不同类型的单个通用接口?