Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Property einer Klasse als Var-Parameter einer Procedure übergeben (https://www.delphipraxis.net/192646-property-einer-klasse-als-var-parameter-einer-procedure-uebergeben.html)

bernau 8. Mai 2017 10:59

Delphi-Version: 10 Berlin

Property einer Klasse als Var-Parameter einer Procedure übergeben
 
Ich habe folgende Function:

Delphi-Quellcode:
function TTestForm.AssignTheValue(aDescription:string; var aString1: String; aString2: String): Integer;


aString1 soll mit aString2 verglichen werden. Wenn die Werte unterschiedlich sind, dann soll aString1 den Wert von aString2 erhalten und das ganze wird protokolliert.

Gaaaanz einfache Procedure. Nix besonderes.

Nun möchte ich aber an aString1 das Property "Text" eines TEdit übergeben.

Delphi-Quellcode:
  AssignTheValue('Ein Text', MyEdit.Text, 'blub');


Leider bekomme ich beim Compilieren die Fehlermeldung

Code:
[dcc32 Fehler] TestFormm.pas(4419): E2033 Die Typen der tatsächlichen und formalen Var-Parameter müssen übereinstimmen
Teoretisch müsste ich für TEdit eine eigene überladene Procedure Schreiben:

Delphi-Quellcode:
function TTestForm.AssignTheValue(aDescription:string; var aString1: TEdit; aString2: String): Integer;overload;


Aber ich will die Procedure universell halten.


Wie muss ich die Procedure AssignTheValue definieren, damit ich das String-property einer X-Beliebigen Klasse übergeben kann.

Der schöne Günther 8. Mai 2017 11:06

AW: Property einer Klasse als Var-Parameter einer Procedure übergeben
 
Gar nicht. Deine Prozedur kann so bleiben wie sie ist, du kopierst den Property-Wert in eine temporäre String-Variable und danach wieder zurück. Properties können nicht als var/out-Parameter übergeben werden.

bernau 8. Mai 2017 11:18

AW: Property einer Klasse als Var-Parameter einer Procedure übergeben
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1370555)
Gar nicht. Deine Prozedur kann so bleiben wie sie ist, du kopierst den Property-Wert in eine temporäre String-Variable und danach wieder zurück. Properties können nicht als var/out-Parameter übergeben werden.

Schade. Das mit der Temp-Stringvariable wollte ich vermeiden. So hatte ich es bisher gemacht und wollte nun den Code etwas optimieren.

Danke für die Info.

himitsu 8. Mai 2017 11:25

AW: Property einer Klasse als Var-Parameter einer Procedure übergeben
 
Wenn das Property keinen Getter/Setter hätte, könnte man das über ein "böses" rumpointern machen, aber VAR geht vom Prinzip her nunmal nicht, da es eben immer einen Getter und/oder Setter hinter einem Property geben könnte.

Darum gibt es auch immer Probleme, wenn man z.B. einen Record über ein Property raus gibt und da dann nur ein Feld ändern will. (inzwischen wirft Delphi da aber wenigstens eine Warnung)

Bleibt noch die RTTI:
Delphi-Quellcode:
function TTestForm.AssignTheValue(aDescription: String; aObject1: TObject{oder TComponent, bzw. TPersistent}; aPropertyName1, aString2: String): Integer; overload;

bernau 8. Mai 2017 11:29

AW: Property einer Klasse als Var-Parameter einer Procedure übergeben
 
Zitat:

Zitat von himitsu (Beitrag 1370558)
Bleibt noch die RTTI:
Delphi-Quellcode:
function TTestForm.AssignTheValue(aDescription: String; aObject1: TObject{oder TComponent, bzw. TPersistent}; aPropertyName1, aString2: String): Integer; overload;

Yep. Das werde ich wohl so machen.

nahpets 8. Mai 2017 11:30

AW: Property einer Klasse als Var-Parameter einer Procedure übergeben
 
Ich spinne einfach mal ein bisserl rum.

Würde sowas in der Art eine für Dich (sinngemäß) nutzbare Alternative sein?
(ungetestet hingedaddelt, nur so als Idee.)
Delphi-Quellcode:
Type
  tCheckString = record
    Error : Integer;
    Value : String;
  end;

function TTestForm.AssignTheValue(aDescription:string; aString1: String; aString2: String): tCheckString;
begin
  if aString1 < aString2 then begin
    Result.Error := -1;
    Result.Value := aString2;
    WriteToLog(Format('%s: %s < %s',[aDescription, aString1, aString2]));
  end else
  if aString1 > aString2 then begin
    Result.Error := 1;
    Result.Value := aString2;
    WriteToLog(Format('%s: %s > %s',[aDescription, aString1, aString2]));
  end else begin
    Result.Error := 0;
    Result.Value := aString1;
    WriteToLog(Format('%s: %s = %s',[aDescription, aString1, aString2]));
  end;
end;

// Aufruf ungefähr sowas:
var
  CheckString : tCheckString;

begin
  // Gibt beim Aufruf dann statt eines Einzeilers immer 'nen Zweizeiler,
  // aber weniger Aufwand als eine annähernd unüberschaubare Anzahl von Überladungen.
  CheckString := AssignTheValue('Beschreibung', Edit1.Text, 'Vorgabestring');
  if CheckString.Error <> 0 then Edit1.Text := CheckString.Value;

  // Oder so, wenn im Quelltext keine Auswertung von Error notwendig sein sollte.
  Edit1.Text := AssignTheValue('Beschreibung', Edit1.Text, 'Vorgabestring').Value;
end;

himitsu 8. Mai 2017 12:01

AW: Property einer Klasse als Var-Parameter einer Procedure übergeben
 
Edit.SetText hat intern ein
Delphi-Quellcode:
if FValue = Value then Exit;
.
Also wäre bei vielen Property eine zusätliche Prüfung sinnlos/doppelt.

Delphi-Quellcode:
function TTestForm.AssignTheValue(aDescription:string; aString1: String; aString2: String): tCheckString;
const
  CompareOperator: array[TValueRelationship] of string = ('<', '=', '>');
begin
  Result.Error := CompareValue(aString1, aString2);
  Result.Value := aString2; //IfThen({aString1 = aString2} Result.Error=EqualsValue, aString1, aString2);
  WriteToLog(Format('%s: %s %s %s', [aDescription, aString1, CompareOperator[Result.Error], aString2]));
end;
Error?
Sieht eher wie ein "State" (Status) aus.

Uwe Raabe 8. Mai 2017 12:03

AW: Property einer Klasse als Var-Parameter einer Procedure übergeben
 
Zitat:

Zitat von nahpets (Beitrag 1370560)
Delphi-Quellcode:
  // Oder so, wenn im Quelltext keine Auswertung von Error notwendig sein sollte.
  Edit1.Text := AssignTheValue('Beschreibung', Edit1.Text, 'Vorgabestring').Value;

Wenn keine Auswertung des Integer-Results notwendig ist, kann man auch gleich den String zurückgeben.

Delphi-Quellcode:
function TTestForm.AssignTheValue(const aDescription, aString1, aString2: String): String;

nahpets 8. Mai 2017 12:12

AW: Property einer Klasse als Var-Parameter einer Procedure übergeben
 
@himitsu
Naja, in der Aufgabenstellung war halt ein Integer als Rückgabewert der Funktion vorgegeben.

Was genau damit zu passieren hat, weiß ich nicht, könnte also eine Errorcode sein.

Im Beispiel würde ein Status stimmen. Wenn man nur auf gleich - ungleich prüft, könnte man auch Boolean nehmen.

War halt nur 'ne Idee, um irgendwie um das Problem rumzukommen.

Die genaue Ausgestaltung der Funktion dürfte dann von den tatsächlichen Gegebenheiten abhängen.

@Uwe Raabe
Naklar, wenn man den in der Vorgabe genannten Rückgabewert nicht braucht, dann reicht ein String aus.
Dann hätte man in der Vorgabe aber auch ursprünglich eine Prozedure verwenden können.

Bin bei meiner Idee halt mal davon ausgegangen, dass der Rückgabewert der Funktion einen Bedeutung hat und habe ihn halt beibehalten.

Bei meiner Version hat man halt die Option offen, ob man, mit oder ohne Auswertung eines Rückgabewerte, eine Zeichenfolge zuweisen möchte.

Wir sehen jedenfalls: Es scheint eine Reihe von Möglichkeiten für die Lösung der Aufgabenstellung zu geben.

bernau 8. Mai 2017 12:26

AW: Property einer Klasse als Var-Parameter einer Procedure übergeben
 
Danke für eure Antworten.

Die RTTI-Lösung habe ich nun fertig und läuft. Den Rückgabe Wert brauche ich (manchmal), daher kann ich nicht einfach einen String zurückgeben. Wäre aber sonst natürlich auch eine Lösung


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:22 Uhr.

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