Extensions

Extensions are a powerful mechanism that lets you add additional capabilities to an existing type – whether the original type is part of your code base, or imported externally.

For example, you can add commonly needed helper methods to any core framework type such as String or even the base Object type. But they can also be helpful for extending your own types in flexible ways, similar to Partial Classes.

Elements provides two ways to add extensions: Type Extensions and individual Extension Methods (the latter in Oxygene only).

Type Extension

Type Extensions add one or more members to an existing type, which might be declared locally in the same project or externally. The new members added by the extension will appear alongside the regular members of the type, and be available (subject to visibility) everywhere the extension is in scope (i.e. when the namespace the extension is defined in is used/imported).

An extension declaration looks much like a type declaration of its own, but does not in fact declare a new type, merely extends the existing type. Extensions can reside in any namespace, and do not need to be declared within the same namespace as the original type.

The extension (Oxygene and Swift) or __extension (C#) keyword is used to declare a type extension, and a basic declaration looks something like this:

type
  Foo = public extension class(String)
    //...
  end;
public __extension class Foo : String 
{
    //...
}
public extension String 
{
    //...
}

In Oxygene and C#, the extension syntax specified a name for the extension. This name should be unique, and can be descriptive of the goal of the extension (such as String_PathHelpers for an extension to String that adds methods to work with file paths), but it is not otherwise exposed to the consumer of the extension. In Swift, no such name is provided.

Inside the extension declaration, methods and (calculated) properties can be declared using the normal expected syntax.

Note that generally, extensions can only add behavior to the class (e.g. methods and calculated properties), but no additional data (e.g. fields, stored properties or events). That is because the actual class (and with it its memory layout) is most likely defined by an external reference, and cannot be extended.

One exception to this are extensions in Swift that are declared in the same project as the original type. Swift allows such extensions to add fields and stored properties as needed, because all extensions declared in the same project will become part of the actual type (much like Partial Classes in Oxygene and C#).

Extensions can be provided for pretty much every kind of user type – including classes, records/structs, enums and even interfaces/protocols.

Version Notes

Extension support for C# is new in Elements 9.0.

Constraints

Extension Methods

Extension Methods are an older syntax in Oxygene that predate the availability of full-fledged extension classes. They are declared similar to global functions, prefixed with the extension keyword, and the name of the type they are extending:

interface

extension method String.ReversedString: String; public;

implementation

extension method String.ReversedString: String;
begin
  //...
end;

end.

See Also

  • [Category] Aspect
  • Partial Classes