Type Extensions

Type extensions can be used to expand an existing type with new methods or properties. They are similar to Partial Types in concept, with the distinction that they can be applied to all available types, even those originally declared in external libraries or core platform frameworks.

Extensions are most commonly used to add custom helper methods, often specific to a given project or problem set, to a more general type provided by the framework, or to correct perceived omissions from a basic type's API.

For example, a project might choose to extend the String type with convenience methods for common string operations that the project needs, but that are not provided by the actual implementation in the platform.

Extension declarations look like regular Class or Record declarations, except that the class or record keyword is prefixed with the extension Type Modifier. Extensions need to be given a unique name, and state the type they extend in parenthesis, in place of the ancestor. It is common (but not mandatory) to use the original type's name, appended with the unique suffix.

type
  String_Helpers = public extension class(String)
    method NumberOfOcurrencesOfCharacter(aCharacter: Chat): Integer;
  end;

Inside the implementation, the extended type instance can be referred to via self, and all its members can be accessed without prefix, as if the extension method was part of the original type. Note that extensions do not have access to private, protected or assembly and/or protected members. Essentially they underlie the same access controls as any code that is not part of the original type itself.

method NSString_TrimHelpers.stringByTrimmingTrailingCharactersInSet(characterSet NSCharacterSet): NSString;
begin
  var charBuffer: unichar[length];
  self.getCharacters(charBuffer);
  var i := length;
  for i: Int32 := length downto 1 do begin
    if not characterSet.characterIsMember(charBuffer[i-1]) then
      break;
  end;
  result := self.substringWithRange(NSMakeRange(0, i));
end;

Extension types can declare both instances and static members. They can add methods and properties with getter/setter statements, but they cannot add new data storage (such as fields, events, or properties with an implied field), because the underlying structure of the type being extended is fixed and cannot be changed.

Extensible Types

Extensions can be defined for any named type, be it a Class, Record, Interface, Enum, Block or even an Alias to an otherwise unnamed type.

No matter which kind of type is being extended, the extension will always use the class or record keyword.

See Also