Class inheritance can be broken up into three concepts: subtyping, composition, and polymorphism. With alias this
, subtyping and composition are easy, providing a nonpolymorphic type of inheritance.
We will execute the following steps to simulate inheritance with structs:
alias this
with the base type to allow easy access to base members and implicit conversion.The code is as follows:
struct Base { int x; int y; } struct Derived { int dx; int dy; Base base; // a member of the base type - composition alias base this; // then use alias this for subtyping } void operateOnBase(Base base) {} void operateOnDerived(Derived derived) {} Derived d; operateOnBase(d); // works
The alias this
method is invoked in two places: if a member is requested and not found in the outer struct and if implicit conversion to a specific type is attempted. alias this
is implemented as a rewrite of the expression to automatically add a reference to the member.
For example, when you write derived.x
, x
is not found in the outer structure, so the compiler attempts to rewrite it as derived.base.x
. Similarly, implicit conversion is implemented by the compiler rewriting it in terms of the alias this
member—when you pass it to the operateOnBase
function, the compiler rewrites the argument d
into the alias this
member. It works exactly as it would if you write operateOnBase(d.base)
.
If the alias this
member is a value type, the rewrite also yields a value. Thus, our call to operateOnBase
will not update d
—it will be passed by a value. If you want reference semantics in the function, you may write ref Base base
in the function declaration. alias this
has no runtime cost.
3.144.28.70