Grundsätzlich möchte ich eine Klasse in der Lage sein, zwei verschiedene Versionen der gleichen generischen Schnittstelle zu implementieren.Do Generics vermasseln Interface Name Mapping?
Betrachten Sie diesen Code
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;
Die erste Showmessage zeigt 'Blah', wie ich erwarten würde, aber die zweite stürzt ab. Der Grund dafür ist, dass der Aufruf T2Val() anstelle von Val() aufruft, wie ich es erwartet hätte. Offensichtlich bildet die Konfliktauflösungszuordnung die Methode für beide Arten von Schnittstellen ab und nicht nur für ITest: T2.
Also, hier ist meine Frage (n).
Ist das ein Fehler? Womit, ich meine, wollte Embarcadero dies unterstützen und einfach falsch umsetzen? Oder hatten sie niemals die Absicht, Programmierern zu erlauben, so etwas überhaupt zu machen? (Ehrlich gesagt, war ich ein wenig überrascht, dass mein Testprogramm sogar kompiliert)
Wenn dies ein Fehler ist, hat jemand eine Idee, wenn es eine Problemumgehung geben könnte, um eine Klasse zu haben zwei verschiedene Arten von einem generischen unterstützen Schnittstelle?
Huh. Gut zu wissen. Vielen Dank. Du bist nur eine Goldmine von Informationen Barry. Danke dass du dir die Zeit nimmst. – TrespassersW
D2010 hat schon diesen Hash, Barry? –
Es tut es leider nicht. Ich sollte es mir wirklich anschauen. –