Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delphi property read/write

is it possible to have different kind of results when declaring property in delphi class?

Example:

property month: string read monthGet(string) write monthSet(integer);

In the example, I want, with the property month, that when I : READ, I get a string; SET, I set an integer;

like image 666
img.simone Avatar asked Oct 31 '14 10:10

img.simone


3 Answers

That is not possible. But properties do not have to correspond to internal storage directly, so you can do:

private
  FMonth: Integer;
  function GetMonthName: string;
...
  property Month: Integer read FMonth write FMonth;
  property MonthName: string read GetMonthName;
...

procedure TMyClass.GetMonthName: string;
begin
  // code that finds name that corresponds to value of FMonth and returns it in Result.
end;

In other words, you'll have to use two properties, one write-only (or normal), one read-only.

like image 33
Rudy Velthuis Avatar answered Nov 19 '22 22:11

Rudy Velthuis


The closest you can get is to use Operator Overloading but the Getter/Setter must be the same type. There is no way to change that.

program so_26672343;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils;

type
  TMonth = record
  private
    FValue: Integer;
    procedure SetValue( const Value: Integer );
  public
    class operator implicit( a: TMonth ): string;
    class operator implicit( a: Integer ): TMonth;
    property Value: Integer read FValue write SetValue;
  end;

  TFoo = class
  private
    FMonth: TMonth;
  public
    property Month: TMonth read FMonth write FMonth;
  end;

  { TMonth }

class operator TMonth.implicit( a: TMonth ): string;
begin
  Result := 'Month ' + IntToStr( a.Value );
end;

class operator TMonth.implicit( a: Integer ): TMonth;
begin
  Result.FValue := a;
end;

procedure TMonth.SetValue( const Value: Integer );
begin
  FValue := Value;
end;

procedure Main;
var
  LFoo: TFoo;
  LMonthInt: Integer;
  LMonthStr: string;
begin
  LFoo := TFoo.Create;
  try
    LMonthInt := 4;
    LFoo.Month := LMonthInt;
    LMonthStr := LFoo.Month;
  finally
    LFoo.Free;
  end;
end;

begin
  try
    Main;
  except
    on E: Exception do
      Writeln( E.ClassName, ': ', E.Message );
  end;

end.
like image 159
Sir Rufo Avatar answered Nov 19 '22 21:11

Sir Rufo


You can't directly do that in Delphi.


What you can do is having a "casting property" like:

private
  //...
  intMonth: integer
  //...
public
  //...
  property StrMonth: string read GetStrMonth write SetStrMonth;
  property IntMonth: integer read intMonth write intMonth;
  //...
end;

function YourClass.GetStrMonth: string;
begin
  case intMonth of
    1: Result := "January";
    //...
  end;
end;

procedure YourClass.SetStrMonth(Value: string);
begin
  if StrMonth = "January" then
    intMonth := 1;
    //...
  end;
end;
like image 1
mg30rg Avatar answered Nov 19 '22 23:11

mg30rg