AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Fluent Design und Records

Ein Thema von hschmid67 · begonnen am 23. Aug 2019 · letzter Beitrag vom 26. Aug 2019
Antwort Antwort
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.045 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#1

AW: Fluent Design und Records

  Alt 23. Aug 2019, 11:56
Ihr meint sicher Fluent Interface und nicht Fluent Design.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
hschmid67

Registriert seit: 2. Jul 2012
Ort: Weilheim i. Obb.
75 Beiträge
 
Delphi 12 Athens
 
#2

AW: Fluent Design und Records

  Alt 23. Aug 2019, 12:52
Zitat:
Ihr meint sicher Fluent Interface und nicht Fluent Design.
Oh, natürlich meinte ich Fluent Interface - Danke für die Klarstellung.

Und vielen Dank auch an alle, die sich bisher beteiligt hatten. Hmmm, das mit der Adresse und dem ^ ist eine Lösung, aber irgendwie mag ich solche Operatoren in meinem normalen Code nicht - das sieht für mich immer nach Eingriff auf unterster Ebene aus. Und das ist in einer Bibliothek ok, aber für den täglichen Gebrauch... Ob ich dann wohl doch lieber bei den Interfaces bleibe?

Viele Grüße
Harald
Harald Schmid

Geändert von hschmid67 (23. Aug 2019 um 12:54 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von uligerhardt
uligerhardt

Registriert seit: 19. Aug 2004
Ort: Hof/Saale
1.749 Beiträge
 
Delphi 2007 Professional
 
#3

AW: Fluent Design und Records

  Alt 24. Aug 2019, 12:51
Hmmm, das mit der Adresse und dem ^ ist eine Lösung, aber irgendwie mag ich solche Operatoren in meinem normalen Code nicht - das sieht für mich immer nach Eingriff auf unterster Ebene aus. Und das ist in einer Bibliothek ok, aber für den täglichen Gebrauch... Ob ich dann wohl doch lieber bei den Interfaces bleibe?
Mit dem Haken siehst du halt, dass du dereferenzierst. Bei Variablen von Klassen- oder Interfacetypen dereferenzierst du genau so, nur ist es versteckt. De facto ist die zweite Variante also sogar weniger klar. (Vom erhöhten Overhead (dynamische Allozierung, virtuelle Methodenaufrufe) ganz zu schweigen.)
Uli Gerhardt
  Mit Zitat antworten Zitat
hschmid67

Registriert seit: 2. Jul 2012
Ort: Weilheim i. Obb.
75 Beiträge
 
Delphi 12 Athens
 
#4

AW: Fluent Design und Records

  Alt 24. Aug 2019, 14:36
Hallo Zusammen,

jetzt habe ich den Vorschlag von uligerhardt mal ausprobiert, aber irgendwas scheine ich nicht richtig zu verstehen. Könnt Ihr mir nochmal weiterhelfen?

Also, ich hab mal folgende Unit gemacht:

Delphi-Quellcode:
unit hs.str2;

interface

type
  ThsStr2 = record
    FStr: string;
    function AsString: string;
    function Init(const mString: string): ThsStr2;
  end;

implementation

uses
  System.SysUtils;

{ ThsStr2 }

function ThsStr2.AsString: string;
begin
  Result := FStr;
end;

function ThsStr2.Init(const mString: string): ThsStr2;
begin
  FStr := mString;
// Result := @Self; // so war der Vorschlag, aber das kompiliert gar nicht "Pointer und ThsStr2"
  Result := ThsStr2(@Self); // so kompiliert es, aber wirft eine AV bei der Ausführung
end;

end.
Testen wollte ich das Ganze so:

Delphi-Quellcode:
procedure Test;
var
  lStr: ThsStr2;
  lDummy: string;
begin
  lDummy := lStr.Init('dummy').AsString;
end;
Aber eben beim Init bekomme ich eine AV. Was mache ich falsch - oder wo ist mein Denkfehler?

Viele Grüße
Harald
Harald Schmid
  Mit Zitat antworten Zitat
Benutzerbild von uligerhardt
uligerhardt

Registriert seit: 19. Aug 2004
Ort: Hof/Saale
1.749 Beiträge
 
Delphi 2007 Professional
 
#5

AW: Fluent Design und Records

  Alt 24. Aug 2019, 14:42
Sorry, ich hab's etwas kurz erklärt.
Du musst einen Zeigertyp zurückgeben, also etwas so:
Delphi-Quellcode:
type
  PhsStr2 = ^ThsStr2; // Zeiger auf ThsStr2
  ThsStr2 = record
    FStr: string;
    function AsString: string;
    function Init(const mString: string): PhsStr2; // <== Beachte den Rückgabetyp!
  end;
Uli Gerhardt
  Mit Zitat antworten Zitat
hschmid67

Registriert seit: 2. Jul 2012
Ort: Weilheim i. Obb.
75 Beiträge
 
Delphi 12 Athens
 
#6

AW: Fluent Design und Records

  Alt 24. Aug 2019, 14:59
Super!

Vielen, vielen Dank. Jetzt hab ich es verstanden.

Hier noch mein vollständiges Beispiel, das jetzt funktioniert (natürlich nur im Anfangsstadium):

Delphi-Quellcode:
unit hs.str2;

interface

type
  PhsStr2 = ^ThsStr2;
  ThsStr2 = record
    FStr: string;
    function Init(const mString: string): PhsStr2;
    class operator implicit(const aValue: ThsStr2): string;
    class operator implicit(const aValue: string): ThsStr2;
  end;

implementation

uses
  System.SysUtils;

{ ThsStr2 }

class operator ThsStr2.implicit(const aValue: ThsStr2): string;
begin
  Result := aValue.FStr;
end;

class operator ThsStr2.implicit(const aValue: string): ThsStr2;
begin
  Result.FStr := aValue;
end;

function ThsStr2.Init(const mString: string): PhsStr2;
begin
  FStr := mString;
  Result := @Self;
end;

end.
Und der Aufruf läuft jetzt erfolgreich:

Delphi-Quellcode:
procedure Test;
var
  lStr: ThsStr2;
  lDummy: string;
begin
  lDummy := lStr.Init('dummy');
end;
Genau das, was ich gesucht hatte - und in meinen Augen dann richig schöner Code, denn man kann das Ganze ja beliebig erweitern, etwa


lDummy := lStr.Init('dummy').CopyFromChar('-').CopyToChar('#');

Das möchte ich nämlich gerade machen: All meine String-Funktionen in einen Aufruf, in ein Objekt/einen Record zu packen, ohne globale Proceduren oder besonderes Speichermanagement (zumindest nicht sichtbar).

Jetzt wäre es nur noch schön, wenn man es so aufrufen könnte:


lDummy := lStr('dummy').CopyFromChar('-').CopyToChar('#');

also ohne das Init, aber das geht wohl nicht...

Vielen Dank und viele Grüße
Harald
Harald Schmid
  Mit Zitat antworten Zitat
Benutzerbild von uligerhardt
uligerhardt

Registriert seit: 19. Aug 2004
Ort: Hof/Saale
1.749 Beiträge
 
Delphi 2007 Professional
 
#7

AW: Fluent Design und Records

  Alt 24. Aug 2019, 15:06
Schaut gut aus. Bzgl. des letzten Satzes: Du könntest dem Record einen Konstruktor oder eine Factory-Funktion verpassen. Dann solltest du so etwas schreiben können:
Delphi-Quellcode:
lDummy := ThsStr2.Create('dummy').CopyFromChar('-').CopyToChar('#'); // Mit Record-Konstruktor
// oder
lDummy := MakehsStr2('dummy').CopyFromChar('-').CopyToChar('#'); // Mit Factory-Funktion
Uli Gerhardt
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:00 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz