Thema: Delphi into Record?

Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.016 Beiträge
 
Delphi 12 Athens
 
#6

AW: into Record?

  Alt 28. Aug 2022, 02:48
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 = 'Testthen ; // -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.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (28. Aug 2022 um 03:06 Uhr)
  Mit Zitat antworten Zitat