Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - property Nummer(Int) read GetNr(Int) write SetNr(Str)


Jakane - Di 15.04.14 08:53
Titel: property Nummer(Int) read GetNr(Int) write SetNr(Str)
Hallo liebe Delphi-Helfer :)

Ich habe einen Wert der mal als A10203 und mal als 10203 reinkommt.

Ist aber beides die selbe Nummer.

Die Nummer soll als Integer zurückgegeben und auch als Integer verarbeitet werden.
Der Buchstabe, so vorhanden, kommt in eine seperate Variable.

Aber die Nummer kommt so nun eigendlich als String rein und nicht als Integer.
Und ich will nicht extra eine Funktion schreiben die mir die Beiden vorher schon trennt.

Gibt es eine Möglichkeit eine property zu definieren,
die mit String geschrieben wird, deren Variable und Lesen aber auf Integer beruht?


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
  private
    FNummer: Integer;
    FKey: Char;
  public
    procedure SetNummer(Value: String);
    function GetNummer: Integer;
  published
    property Personalnummer: Integer read GetPersonalnummer write SetPersonal;
  end;


Nersgatt - Di 15.04.14 09:07

Du könntest die Property als Variant deklarieren und dann im Setter den Wert zerlegen.
Das hat natürlich den Nachteil, dass man auch völligen Quatsch übergeben könnte. In dem Fall würde ich einfach eine Exception auslösen.
Der weitere Nachteil ist, dass Du die Nummer auch als Variant wieder zurückgeben musst im Getter.

Sö könnte das aussehen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
  private
    FNummer: Integer;
    FKey: Char;
  public
    procedure SetNummer(Value: Variant);
    function GetNummer: Variant;
  published
    property Nummer: Variant read GetNummer write SetNummer;
  end;


In SetNummer würdest Du den Wert nun ggf. zerlegen.
Die Lösung finde ich allerdings nicht sonderlich schön, weil sie nicht das macht, was man von einer Property erwartet.

Ich würde eine weitere Methode deklarieren, um den Wert zu übergeben:


Delphi-Quelltext
1:
2:
  published
    procedure WriteWert(AWert : Variant);


Nun würde ich in WriteWert das Dingen zerlegen und FNummer und FKey füllen.
Zum Lesen würde ich dann 2 readonly-Properties erstellen:

Delphi-Quelltext
1:
2:
    property Nummer: Integer read FNummer;
    property Key : String Read FKey;


Nun wäre das sauber getrennt, in den Properties wird mit den richtigen Datentypen gearbeitet.


jaenicke - Di 15.04.14 09:14

Bis Delphi 2005 nur als Variant und das ist weniger empfehlenswert. Ab Delphi 2006 geht das hingegen sehr gut:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
  TStaffNumber = record
  strict private
    Value: Integer;
  public
    class operator implicit(const AValue: string): TStaffNumber;
    class operator implicit(const AValue: Integer): TStaffNumber;
    class operator implicit(const AValue: TStaffNumber): Integer;
    class operator implicit(const AValue: TStaffNumber): string;
  end;

  TTest = class
  private
    FStaffNumber: TStaffNumber;
    procedure SetStaffNumber(const Value: TStaffNumber);
  public
    property StaffNumber: TStaffNumber read FStaffNumber write SetStaffNumber;
  end;

{ TTest }

procedure TTest.SetStaffNumber(const Value: TStaffNumber);
begin
  FStaffNumber := Value;
end;

{ TStaffNumber }

class operator TStaffNumber.implicit(const AValue: string): TStaffNumber;
begin
  Result.Value := StrToInt(Copy(AValue, 2));
end;

class operator TStaffNumber.implicit(const AValue: Integer): TStaffNumber;
begin
  Result.Value := AValue;
end;

class operator TStaffNumber.implicit(const AValue: TStaffNumber): Integer;
begin
  Result := AValue.Value;
end;

class operator TStaffNumber.implicit(const AValue: TStaffNumber): string;
begin
  Result := IntToStr(AValue.Value);
end;
Und die Benutzung:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
var
  Test: TTest;
begin
  Test := TTest.Create;
  try
    Test.StaffNumber := 10203;
    ShowMessage(Test.StaffNumber); // 10203
    Test.StaffNumber := 'A10204';
    ShowMessage(IntToStr(Test.StaffNumber)); // 10204
  finally
    Test.Free;
  end;


Jakane - Di 15.04.14 10:38

Ok werd ich ausprobieren, danke :)