Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Record als Prozedurparameter: Werte direkt übergeben (https://www.delphipraxis.net/197084-record-als-prozedurparameter-werte-direkt-uebergeben.html)

Codehunter 17. Jul 2018 07:14

Delphi-Version: 10.2 Tokyo

Record als Prozedurparameter: Werte direkt übergeben
 
Ahoi,

ich habe eine Prozedur mit einem Record als Parameter. Ist es möglich, im Prozeduraufruf die Felder des Records direkt anzugeben. Etwa so wie unten exemplarisch gezeigt?
Delphi-Quellcode:
type
  TMyRecord = record
    FeldA: string;
    FeldB: Integer;
    FeldC: string;
  end;

{...}

procedure Test(Param: TMyRecord);
begin
  {...}
end;

procedure Produce;
begin
  Test(['Foo', 1, 'Bar']);
end;

Jasocul 17. Jul 2018 07:25

AW: Record als Prozedurparameter: Werte direkt übergeben
 
Da ich neugierig bin, ob sowas einfach geht, habe ich Google bemüht und diesen Treffer bekommen.
Macht einen ziemlich vollständigen Eindruck, wie man das realisieren kann.

SebastianZ 17. Jul 2018 07:27

AW: Record als Prozedurparameter: Werte direkt übergeben
 
Zitat:

Zitat von Codehunter (Beitrag 1407466)
Ahoi,

ich habe eine Prozedur mit einem Record als Parameter. Ist es möglich, im Prozeduraufruf die Felder des Records direkt anzugeben. Etwa so wie unten exemplarisch gezeigt?
Delphi-Quellcode:
type
  TMyRecord = record
    FeldA: string;
    FeldB: Integer;
    FeldC: string;
  end;

{...}

procedure Test(Param: TMyRecord);
begin
  {...}
end;

procedure Produce;
begin
  Test(['Foo', 1, 'Bar']);
end;


Ich baue für sowas meist eine class function in den Record, die ermöglicht:

Delphi-Quellcode:
  TMyRecord = record
    FeldA: string;
    FeldB: Integer;
    FeldC: string;
    class function Init(const AFieldA: String; AFieldB: Integer; AFieldC: String): TMyRecord ; static;
  end;

class function TMyRecord.Init(const AFieldA: String; AFieldB: Integer; AFieldC: String): TMyRecord ;
begin
  Result.FeldA:= AFieldA
  Result.FeldB:= AFieldB
  Result.FeldC:= AFieldC
end;

procedure Produce;
begin
  Test(TMyRecord.Init('Foo', 1, 'Bar'));
end;

Der schöne Günther 17. Jul 2018 07:35

AW: Record als Prozedurparameter: Werte direkt übergeben
 
Dumme Frage: Macht es praktisch einen Unterschied ob man dem Record nun eine
Delphi-Quellcode:
static class function Init(..)
oder einen
Delphi-Quellcode:
constructor Create(..)
gibt?

Codehunter 17. Jul 2018 07:49

AW: Record als Prozedurparameter: Werte direkt übergeben
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1407470)
Dumme Frage: Macht es praktisch einen Unterschied ob man dem Record nun eine
Delphi-Quellcode:
static class function Init(..)
oder einen
Delphi-Quellcode:
constructor Create(..)
gibt?

Würde mich auch interessieren. Ich habe mir Konstruktoren in Records abgewöhnt und verwende auch class procedure Init(), obwohl ich das Schlüsselwort class in dem Zusammenhang etwas unpassend finde. Bei TFormatSettings wird eine class function Create() verwendet.

KodeZwerg 17. Jul 2018 07:55

AW: Record als Prozedurparameter: Werte direkt übergeben
 
Ich mag das TPoint Beispiel.
Delphi-Quellcode:
type
  TPoint = record
    X,Y integer
  end;

function Point( X, Y : integer ) : TPoint;
begin
  Result.X := X;
  Result.Y := Y;
end;

Codehunter 17. Jul 2018 08:05

AW: Record als Prozedurparameter: Werte direkt übergeben
 
Zitat:

Zitat von KodeZwerg (Beitrag 1407475)
Ich mag das TPoint Beispiel.

Huh. Das ist so .... Delphi 1 :lol:

jaenicke 17. Jul 2018 08:27

AW: Record als Prozedurparameter: Werte direkt übergeben
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1407470)
Dumme Frage: Macht es praktisch einen Unterschied ob man dem Record nun eine
Delphi-Quellcode:
static class function Init(..)
oder einen
Delphi-Quellcode:
constructor Create(..)
gibt?

Vom generierten Code her nicht. Ich persönlich finde den Konstruktor sinnvoller, da man dann sofort weiß was da passieren soll. Schließlich gibt es den in Records genau dafür. Bei anderen Klassenmethoden muss man immer erst nachschauen was die eigentlich machen, wenn man fremden Code liest.

TiGü 17. Jul 2018 08:30

AW: Record als Prozedurparameter: Werte direkt übergeben
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1407470)
Dumme Frage: Macht es praktisch einen Unterschied ob man dem Record nun eine
Delphi-Quellcode:
static class function Init(..)
oder einen
Delphi-Quellcode:
constructor Create(..)
gibt?

Schauen wir es uns anhand eines praktischen Beispiels an:

Delphi-Quellcode:
program Project5;

{$APPTYPE CONSOLE}

{$R *.res}


uses
  System.SysUtils;

type
  TMyRecord2 = record
    FeldB: Integer;
    class function Init(AFieldB: Integer): TMyRecord2; static;
  end;

  TMyRecord = record
    FeldB: Integer;
    constructor Create(AFieldB: Integer);
  end;

  { TMyRecord }

constructor TMyRecord.Create(AFieldB: Integer);
begin
  FeldB := AFieldB;
end;

{ TMyRecord2 }

class function TMyRecord2.Init(AFieldB: Integer): TMyRecord2;
begin
  Result.FeldB := AFieldB;
end;

var
  MyRecord: TMyRecord;
  MyRecord2: TMyRecord2;

begin
  MyRecord := TMyRecord.Create(123);
  MyRecord2 := TMyRecord2.Init(123);
end.

Ergibt für die beiden Zuweisungen folgenden Assembler-Code:

Code:
Project5.dpr.41: MyRecord := TMyRecord.Create(123);
0041C554 8D45EC          lea eax,[ebp-$14]
0041C557 BA7B000000       mov edx,$0000007b
0041C55C E873D7FFFF      call TMyRecord.Create
0041C561 8B45EC          mov eax,[ebp-$14]
0041C564 A3B8484200       mov [$004248b8],eax
Project5.dpr.42: MyRecord2 := TMyRecord2.Init(123);
0041C569 B87B000000       mov eax,$0000007b
0041C56E E87DD7FFFF      call TMyRecord2.Init
0041C573 A3BC484200       mov [$004248bc],eax
Code:
Project5.dpr.25: begin
00419CD4 55               push ebp
00419CD5 8BEC            mov ebp,esp
00419CD7 83C4F8           add esp,-$08
00419CDA 8955F8           mov [ebp-$08],edx
00419CDD 8945FC          mov [ebp-$04],eax
Project5.dpr.26: FeldB := AFieldB;      // Zuweisung im Create
00419CE0 8B45FC          mov eax,[ebp-$04]
00419CE3 8B55F8           mov edx,[ebp-$08]
00419CE6 8910             mov [eax],edx
Project5.dpr.27: end;
00419CE8 8B45FC          mov eax,[ebp-$04]
00419CEB 59               pop ecx
00419CEC 59               pop ecx
00419CED 5D              pop ebp
00419CEE C3               ret
00419CEF 90               nop
Project5.dpr.32: begin
00419CF0 55               push ebp
00419CF1 8BEC            mov ebp,esp
00419CF3 83C4F8           add esp,-$08
00419CF6 8945FC          mov [ebp-$04],eax
Project5.dpr.33: Result.FeldB := AFieldB;     // Zuweisung im Init
00419CF9 8B45FC          mov eax,[ebp-$04]
00419CFC 8945F8           mov [ebp-$08],eax
Project5.dpr.34: end;
00419CFF 8B45F8           mov eax,[ebp-$08]
00419D02 59               pop ecx
00419D03 59               pop ecx
00419D04 5D              pop ebp
00419D05 C3               ret
00419D06 8BC0             mov eax,eax

Uwe Raabe 17. Jul 2018 08:31

AW: Record als Prozedurparameter: Werte direkt übergeben
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1407470)
Macht es praktisch einen Unterschied ob man dem Record nun eine
Delphi-Quellcode:
static class function Init(..)
oder einen
Delphi-Quellcode:
constructor Create(..)
gibt?

Eigentlich nur diesen: E2394 Parameterlose Konstruktoren sind in Record-Typen nicht zulässig

Parameterlose Static Class Functions gehen aber schon.


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:24 Uhr.
Seite 1 von 3  1 23      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz