img.simone
img.simone

Reputation: 742

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;

Upvotes: 6

Views: 17523

Answers (4)

Sir Rufo
Sir Rufo

Reputation: 19096

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.

Upvotes: 8

David Heffernan
David Heffernan

Reputation: 612794

There's no way to do that for a property. A property has a single type.

The obvious way to achieve you goal is to have getter and setter functions that you use directly.

function GetMonth: string;
procedure SetMonth(Value: Integer);

You might decide to make the type part of the name to reduce confusion in the calling code. Say GetMonthStr and SetMonthOrd.

You could expose these functions as two separate properties. One read only, the other write only.

Upvotes: 1

mg30rg
mg30rg

Reputation: 1349

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;

Upvotes: 1

Rudy Velthuis
Rudy Velthuis

Reputation: 28806

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.

Upvotes: 4

Related Questions