Property expressions

Top  Previous  Next

Property expressions

In Object Pascal a property is an exposed value that can either be linked to a class-field or a class-member method. This is the traditional way of exposing a value property, where the consumer of the property is abstracted from the reader and writer logic. The consumer does not know if the property is explicitly linked to a field or a writer method.

 

Smart Pascal has full support for the older paradigm but introduces a technique called "property expressions". It basically allows you to program reader and writer logic as a part of property declarations. This is completely unheard of under traditional Object Pascal, but common in other languages like C# and Objective-C.

 

In classical Object Pascal you could write something like this:

 

Type
TMyObject = Class( .. )
private
  FSubObj: TNameData;
protected
  function getFirstName:String;
  procedure setFirstName(value:String);
published
  Property FirstName:String read getFirstName write setFirstName;
end;
 
function TMyObject.getFirstName:String;
begin
  result:=FSubObj.FirstName;
end;
 
procedure TMyObject.setFirstName(value:String);
begin
  FSubObj.FirstName:=Value;
end;

 

Using Smart Pascal with property expressions, you can omit the getFirstName() and setFirstName() stubs - and implement the logic as part of the property declaration itself:

 

Property FirstName:String
              read ( FSubObject.FirstName )
              write ( FSubObject.FirstName );

 

Property expressions is especially handy for classes with child objects. If a class exposes sub objects (object lists) you had, prior to generics, to write a lot of the same code over and over again, wrapping already existing code in a list object - which for complex class hierarchies reduces execution speed with unnecessary bloat. This has changed for the better with the introduction of generics, but you still have to isolate reader and writer logic in distinct class members.

Under Smart Pascal this is elegantly achieved using arrays:

 

TMyClass = class
   private
      FList : array of TElement;
   public
      property Items[i: Integer] : TElement read (FList[i]) 
                                            write (FList[i]); default;
      property Count : Integer read (FList.Length);
end;

 

The technique greatly simplifies number conversion, which can in some cases be done directly in the declaration:

 

TMyAngle = record
   private
      FAngle : Float;
   public
      property Radians : Float read FAngle write FAngle;
      property Degrees : Float read (RadToDeg(FAngle)) 
                               write (FAngle:=DegToRad(Value));
end;

 

See Properties