Ich hab da mal bissl rumgespielt.
Einmal hätte ich ja das Problem, dass der Record sich unterschiedlich verhalten soll,
jenachdem von wo er kommt -> Property oder Variable.
Und wenn ich zwei Records habe, dass sie aber dennoch zuweisungskompatibel sind.
Kein Problem mit den ClassOperatoren, aber mit den Generics hatte ich sowas noch nie mit sich selbst probiert.
Versuch 1 (Idee siehe vorheriger Post) lief schief, da ich von SELF keinen Typ bekomme (falls der überhaupt sich unterscheiden hätte, was ich kaum glaube).
Dabei wäre Dieses die einfachste/übersichtlichste Lösung geworden.
Delphi-Quellcode:
uses
TypInfo;
type
TFuu = record
procedure Test;
end;
TBar = type TFuu;
procedure TForm11.FormCreate(Sender: TObject);
var
A: TBar;
begin
A.Test;
end;
procedure TFuu.Test;
begin
ShowMessage(PTypeInfo(TypeInfo(Self)).Name); // geht nicht
end;
Versuch 2 klappte dann erstmal.
Zwar wieder kein Typ von Self, aber dafür von <T>.
Aber dennoch nicht funktional, da diese Typen sich nicht einander zuweisen lassen.
Delphi-Quellcode:
uses
TypInfo;
type
TFuu<T> = record
procedure Test;
end;
TFuu = TFuu<Byte>;
TBar = TFuu<Word>;
procedure TForm11.FormCreate(Sender: TObject);
var
A: TBar;
begin
A.Test;
end;
procedure TFuu<T>.Test;
begin
//ShowMessage(PTypeInfo(TypeInfo(Self)).Name); // geht auch nicht
ShowMessage(PTypeInfo(TypeInfo(T)).Name);
end;
Versuch 3 ... naja
Delphi-Quellcode:
type
TFuu<X> = record
procedure Test;
class operator Implicit(const A: TFuu<Word>): TFuu<Byte>;
class operator Implicit(const A: TFuu<Byte>): TFuu<Word>;
end;
[dcc32 Fehler] E2521 Operator 'Implicit' muss einen 'TFuu<X>'-Typ im Parameter oder Ergebnistyp übernehmen
Delphi-Quellcode:
type
TFuu<X> = record
procedure Test;
class operator Implicit(const A: TFuu<X>): TFuu<Byte>;
class operator Implicit(const A: TFuu<X>): TFuu<Word>;
class operator Implicit(const A: TFuu<Word>): TFuu<X>;
class operator Implicit(const A: TFuu<Byte>): TFuu<X>;
end;
Also genau was der Compiler nun wollte, aber dennoch mag er es nun nicht, wegen der Nicht-Eindeutigkeit.
Erstes und Letztes sind identisch und verweisen auch noch jeweils auf sich selber.
Delphi-Quellcode:
// z.B. X = Byte
class operator Implicit(const A: TFuu<Byte>): TFuu<Byte>;
class operator Implicit(const A: TFuu<Byte>): TFuu<Word>;
class operator Implicit(const A: TFuu<Word>): TFuu<Byte>;
class operator Implicit(const A: TFuu<Byte>): TFuu<Byte>;
Dann, bei der 4, wurde es kompliziert und fast unübersichtlich (hatte mehrmals 'nen Knoten im Hirn und dachte es sei andersrum),
ABER es scheint zu gehn.
Delphi-Quellcode:
uses
TypInfo;
type
TFuu<X,Y> = record
Value: string;
procedure Test;
class operator Implicit(const A: TFuu<X,Y>): TFuu<Y,X>;
class operator Implicit(const A: TFuu<Y,X>): TFuu<X,Y>;
class operator Initialize(out Dest: TFuu<X,Y>);
class operator Finalize (var Dest: TFuu<X,Y>);
class operator Assign (var Dest: TFuu<X,Y>; const [ref] Src: TFuu<X,Y>);
end;
TFuu = TFuu<Byte,Word>;
TBar = TFuu<Word,Byte>;
procedure TForm11.FormCreate(Sender: TObject);
var
F: TFuu;
Q: TFuu;
B: TBar;
begin // create TFuu(F), create TFuu(Q), create TBar(B)
F.Test; // test TFuu(F)
B.Test; // test TBar(B)
F.Value := 'Test'; // -setValue TFuu(F)-
Q := F; // assign TFuu(F)->TFuu(Q)
B := F; // create TBar(Temp), toMe TFuu(F)->TBar(Temp), assign TBar(Temp)->TBar(B), free TBar(Temp)
if B.Value = 'Test' then ; // -getValue TFuu(B)-
end; // free TBar(B), free TFuu(Q), free TFuu(F)
procedure TFuu<X,Y>.Test;
begin
//ShowMessage(PTypeInfo(TypeInfo(X)).Name + ' ' + PTypeInfo(TypeInfo(Y)).Name);
if TypeInfo(X) = TypeInfo(Byte) then
ShowMessage('test TFuu')
else
ShowMessage('test TBar');
end;
class operator TFuu<X,Y>.Assign(var Dest: TFuu<X,Y>; const [ref] Src: TFuu<X,Y>);
begin
if TypeInfo(X) = TypeInfo(Byte) then
ShowMessage('assign TFuu->TFuu')
else
ShowMessage('assign TBar->TBar');
Dest.Value := Src.Value;
end;
class operator TFuu<X,Y>.Finalize(var Dest: TFuu<X,Y>);
begin
if TypeInfo(X) = TypeInfo(Byte) then
ShowMessage('free TFuu')
else
ShowMessage('free TBar');
Dest.Value := '';
end;
class operator TFuu<X,Y>.Initialize(out Dest: TFuu<X,Y>);
begin
if TypeInfo(X) = TypeInfo(Byte) then
ShowMessage('create TFuu')
else
ShowMessage('create TBar');
Dest.Value := 'empty';
end;
class operator TFuu<X,Y>.Implicit(const A: TFuu<Y,X>): TFuu<X,Y>;
begin
//ShowMessage(PTypeInfo(TypeInfo(Y)).Name + ' ' + PTypeInfo(TypeInfo(X)).Name
// + ' -> ' + PTypeInfo(TypeInfo(X)).Name + ' ' + PTypeInfo(TypeInfo(Y)).Name);
if TypeInfo(X) = TypeInfo(Byte) then
ShowMessage('toMe TBar->TFuu')
else
ShowMessage('toMe TFuu->TBar');
//Result := TFuu<X,Y>(A);
Result.Value := A.Value;
end;
class operator TFuu<X,Y>.Implicit(const A: TFuu<X,Y>): TFuu<Y,X>;
begin
//ShowMessage(PTypeInfo(TypeInfo(X)).Name + ' ' + PTypeInfo(TypeInfo(Y)).Name
// + ' -> ' + PTypeInfo(TypeInfo(Y)).Name + ' ' + PTypeInfo(TypeInfo(X)).Name);
if TypeInfo(X) = TypeInfo(Byte) then
ShowMessage('fromMe TFuu->TBar')
else
ShowMessage('fromMe TBar->TFuu');
//TFuu<X,Y>(Result) := A; // [dcc32 Fehler] E2064 Der linken Seite kann nichts zugewiesen werden
//Result := TFuu<Y,X>(A);
Result.Value := A.Value;
end;
Früher war mir so, als wenn Temp-Variablen für Zwischenergebnisse als lokale Funktionsvariablen (von begin bis end) erstellt würden.
Jetzt scheint das wirklich nur dort zu sein, wo es ist ... vielleicht haben sie nun die neuen inline-Variablen hier selbst benutzt.