An extension on T adds methods callable on values of type T, without subclassing or wrapping.

Program

Play the program to call a custom shout on a plain String.

extensions.dart
Replay: real traced execution (multi-file project)
extension StringExtras on String {
  String shout() => toUpperCase() + '!';
}

void main() {
  var greeting = 'hello';
  print(greeting.shout());
}
  1. greeting ← hello

    5void main() {6  var greeting = 'hello';7  print(greeting.shout());
    values this stephellogreeting
  2. call ← greeting.shout()

    6  var greeting = 'hello';7  print(greeting.shout());8}
    values this stepgreeting.shout()callhellogreeting
  3. return value ← HELLO!

    1extension StringExtras on String {2  String shout() => toUpperCase() + '!';3}
    values this stepHELLO!return valuehellothis
  4. print(greeting.shout());

    6  var greeting = 'hello';7  print(greeting.shout());8}
    outputHELLO!
extension `extension Name on T { ... }` adds members to type `T`.
dot call `greeting.shout()` looks like a normal method call.
no subclass Extensions do not require subclassing or wrapping.