![]() |
Property -> Getter und Setter mit Parametern
Ein Gedankengang zum Thema "wie spare ich Tipperei".
Ich habe ein CustomObject, welches Parameter speichert. Egal wo und wie. Und es gibt eine Ableitung in der ich einige Properties definiere, welche Properties des Parent verwendet. Der Zugriff wird in der Implementation geregelt.
Delphi-Quellcode:
Gibt es einge Möglichkeit den Code zu verkürzen. Ich denke an so etwas wie die direkte Funktionsübergabe mit Parameter. Dann könnte man sich die Implementation sparen.
interface
type TCustomSpeicherobjekt = class(TObject) private function GetEinStringWert(aIndex: string): string; procedure SetEinStringWert(aIndex: string; const Value: string); public property EinStringWert[aIndex:string]:string read GetEinStringWert write SetEinStringWert; end; TMeinSpeicherobjekt = class(TCustomSpeicherobjekt) private function GetWertA: string; function GetWertB: string; procedure SetWertA(const Value: string); procedure SetWertB(const Value: string); public property WertA:string read GetWertA write SetWertA; property WertB:string read GetWertB write SetWertB; end; implementation { TMeinSpeicherobjekt } function TCustomSpeicherobjekt.GetEinStringWert(aIndex: string): string; begin // Hier steht Code zum Lesen end; procedure TCustomSpeicherobjekt.SetEinStringWert(aIndex: string; const Value: string); begin // Hier steht Code zum Schreiben end; { TMeinSpeicherobjekt } function TMeinSpeicherobjekt.GetWertA: string; begin Result:=EinStringWert['WertA']; end; function TMeinSpeicherobjekt.GetWertB: string; begin Result:=EinStringWert['WertB']; end; procedure TMeinSpeicherobjekt.SetWertA(const Value: string); begin EinStringWert['WertA']:=Value; end; procedure TMeinSpeicherobjekt.SetWertB(const Value: string); begin EinStringWert['WertB']:=Value; end; Beispiel:
Delphi-Quellcode:
Oder gibt es andere Ansätze?
TMeinSpeicherobjekt = class(TCustomSpeicherobjekt)
private public // Entweder so property WertA:string read EinStringWert['WertA'] write EinStringWert['WertA']; // oder so property WertB:string read GetEinStringWert('WertB') write SetEinStringWert('WertB'); end; |
AW: Property -> Getter und Setter mit Parametern
Eventuell hilft Dir index als Indexbezeichner. Schau Dir die Hilfe zu properties nochmal an.
![]() Sherlock |
AW: Property -> Getter und Setter mit Parametern
Ich würde dann aber die Stringindizes nicht nach außen geben, um Tippfehler zu minimieren und das z.B. so lösen (wenn die Stringindizes intern notwendig sind):
Delphi-Quellcode:
Dann lässt sich das einfach so nutzen:
{$SCOPEDENUMS ON}
type TCustomSpeicherobjekt = class(TObject) private function GetEinStringWert(aIndex: string): string; procedure SetEinStringWert(aIndex: string; const Value: string); public property EinStringWert[aIndex: string]: string read GetEinStringWert write SetEinStringWert; end; TMeinSpeicherobjekt = class(TCustomSpeicherobjekt) public type TValueInfo = (ValueA, ValueB); private const cValueNames: array[TValueInfo] of string = ('WertA', 'WertB'); function GetValue(ValueKind: TValueInfo): string; procedure SetValue(ValueKind: TValueInfo; const Value: string); public property Value[ValueKind: TValueInfo]: string read GetValue write SetValue; end; implementation { TMeinSpeicherobjekt } function TCustomSpeicherobjekt.GetEinStringWert(aIndex: string): string; begin // Hier steht Code zum Lesen end; procedure TCustomSpeicherobjekt.SetEinStringWert(aIndex: string; const Value: string); begin // Hier steht Code zum Schreiben end; { TMeinSpeicherobjekt } function TMeinSpeicherobjekt.GetValue(ValueKind: TValueInfo): string; begin Result := EinStringWert[cValueNames[ValueKind]]; end; procedure TMeinSpeicherobjekt.SetValue(ValueKind: TValueInfo; const Value: string); begin EinStringWert[cValueNames[ValueKind]] := Value; end;
Delphi-Quellcode:
MyObject.Value[TValueKind.ValueA] := 'Test';
ShowMessage(MyObject.Value[TValueKind.ValueA]); |
AW: Property -> Getter und Setter mit Parametern
Zitat:
Ich suche eine Lösung, in der ich die Implementation übergehen kann. |
AW: Property -> Getter und Setter mit Parametern
Zitat:
|
AW: Property -> Getter und Setter mit Parametern
Zitat:
Dieser Index kann ein Integer oder ein Enum sein. |
AW: Property -> Getter und Setter mit Parametern
Zitat:
|
AW: Property -> Getter und Setter mit Parametern
OK. Ich verbuche das einfach mal unter "geht nicht".
|
AW: Property -> Getter und Setter mit Parametern
Zitat:
Eine davon ist der Einsatz des ModelMaker Code Explorer, den ich in solchen Fällen ja gern als sinnvolles Werkzeug in der IDE anführe. Hier bieten sich verschiedene Möglichkeiten an, um die Tipparbeit einzusparen. Die einfachste ist, man legt einmal ein solches Property "WertA" an und implementiert den Zugriff, wobei der IndexString exakt dem Property-Namen entspricht (wie im Beispiel gezeigt). Dann kopiert man das Property mit dem MMX und benutzt dessen Member-Inplace-Rename-Funktionalität, um das neue Property in "WertB" umzubenennen. Erfreulicherweise werden dabei auch die IndexStrings mit umbenannt. Eine andere Alternative ist das Anlegen eines eigenen Getter/Setter-Templates, das dann bei einem neuen Property zum Einsatz kommt. Aber es geht auch ohne MMX mit dem Vorschlag von jaenicke, wenn man ihn etwas abwandelt (das SCOPEDENUMS ist hier nicht unbedingt notwendig):
Delphi-Quellcode:
TMeinSpeicherobjekt = class(TCustomSpeicherobjekt)
private type {$SCOPEDENUMS ON} TValueInfo = (WertA, WertB); {$SCOPEDENUMS OFF} protected function GetValue(ValueKind: TValueInfo): string; procedure SetValue(ValueKind: TValueInfo; const Value: string); public property WertA: string index TValueInfo.WertA read GetValue write SetValue; property WertB: string index TValueInfo.WertB read GetValue write SetValue; end; uses System.TypInfo; function TMeinSpeicherobjekt.GetValue(ValueKind: TValueInfo): string; begin result := EinStringWert[GetEnumName(TypeInfo(TValueInfo), Ord(ValueKind))]; end; procedure TMeinSpeicherobjekt.SetValue(ValueKind: TValueInfo; const Value: string); begin EinStringWert[GetEnumName(TypeInfo(TValueInfo), Ord(ValueKind))] := Value; end; |
AW: Property -> Getter und Setter mit Parametern
@Uwe: Das ist ein Ansatz, der sehr interessant aussieht.
|
AW: Property -> Getter und Setter mit Parametern
Zitat:
|
AW: Property -> Getter und Setter mit Parametern
Wenn man weniger Tipparbeit haben will, würde ich mal die Programmiersprache wechseln. :stupid:
Diese Klimmzüge, um Getter und Setter über indexe anzusprechen, ist doch ziemlich unsauber und irgendwie von hinten durch die Brust ins Auge. Denn was habe ich im Getter und Setter vermutlich? Ein Case, würde ich mal annehmen. Oder halten wir die Daten etwa in einem Array? |
AW: Property -> Getter und Setter mit Parametern
Zitat:
|
AW: Property -> Getter und Setter mit Parametern
Delphi-Quellcode:
Der Property EinStringWert ist ein Array-Property.
TCustomSpeicherobjekt = class(TObject)
private function GetEinStringWert(aIndex: string): string; procedure SetEinStringWert(aIndex: string; const Value: string); public property EinStringWert[aIndex:string]:string read GetEinStringWert write SetEinStringWert;default; end; Pro Klasse kann man genau ein Array-Property zum Default-Indexer erklären (Schlüsselwort default).
Delphi-Quellcode:
Das spart auch Tipparbeit.
var
x : TCustomSpeicherobjekt; begin x := TCustomSpeicherobjekt.Create; x['Host'] := 'www.delphipraxis.net'; |
AW: Property -> Getter und Setter mit Parametern
Zitat:
Und selbst wenn es nichts mit Persistenz zu tun hat, ist es unsauber, denn die Tatsache, das der Wert 'FooBar' an Stelle 3 im Array stehen soll, ist somit an mehreren Stellen definiert. Ausnahme: Das Array ist ein Ersatz für private Felder. D.h. im Getter/Setter steht nur der Zugriff auf das Array. Dann...Nun ja. Spart man keine Tipparbeit, sondern hat einen Mapper geschrieben. Die Motivation des TE ist TIPPARBEIT SPAREN und nicht, Konstrukte für Index-Properties zu finden, die sinnvoll sind. Zitat:
Delphi-Quellcode:
Das Beispiel stammt aus meinem uralten Code. Kapselung dient ja nicht dazu, schlechten Code zu verbergen. Sollte es zumindest nicht.
Procedure TMyClass.SetValue (Value : TSomeType;Index : Integer);
begin case Index of 0 : StringValues[0] := Value.AsString; 1 : IntegerValues[0] := Value.AsInteger; ... end; Zitat:
Delphi ist nun mal eine Programmiersprache, die von Tastaturherstellern gesponsort wird... |
AW: Property -> Getter und Setter mit Parametern
Zitat:
Sherlock |
AW: Property -> Getter und Setter mit Parametern
Nochmal danke für die Beiträge. Letztendlich gibt es nicht das, was ich mir vorgestellt habe. War ja auch nur ein Gedankengang.
Wichtig ist für mich, daß die Properties bestehen bleiben. Deshalb fällt der Vorschlag von z.B. sx2008 aus. Ausserdem muss der Code lesbar bleiben. Deshalb wäre ein Sprachfeature in der Form von
Delphi-Quellcode:
eine tolle Sache. Damit wäre Tipparbeit erheblich reduziert und der Code ist besonders gut lesbar.
// Entweder so
property WertA:string read EinStringWert['WertA'] write EinStringWert['WertA']; // oder so property WertB:string read GetEinStringWert('WertB') write SetEinStringWert('WertB'); Der Vorschlag von "Uwe Raabe" wäre der besste. Allerdings auch nur, wenn keine Sonderzeichen benötigt werden. Folgendes wäre damit nicht möglich.
Delphi-Quellcode:
property WertA:string read EinStringWert['Wert-A-MitSonderzeichen'] write EinStringWert['Wert-A-MitSonderzeichen'];
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:17 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