CodeBlanks Logo Icon CodeBlanks

Generic extension

Learn to write generic extensions.

Generic extension

A generic extension is an extension that takes a type parameter. The extension ListFirst<T> on List<T> { T? firstOrNull() => isEmpty ? null : first; } declaration safely gets the first element of any list.

Generic extensions preserve type safety: [1, 2].firstOrNull() returns int?, ['a'].firstOrNull() returns String?. The type parameter T is inferred from the target type.

Type inference

In generic extensions, the type parameter is automatically inferred from the target. In extension BoxUnwrap<T> on Box<T> { T unwrap() => value; }, when called on a Box<int>, T becomes int.

The type parameter can also be specified explicitly: box<int>.unwrap(). But in most cases inference is sufficient. Generic extensions are ideal for adding functionality to generic classes or types.

Practice A ListMiddle extension

Define a ListMiddle<T> extension on List<T> with a T? middleOrNull() => isEmpty ? null : this[length ~/ 2]; method. In main add print([1, 2, 3].middleOrNull());.

Starter code

main.dart
void main() {
  // define a ListMiddle<T> extension (on List<T>; middleOrNull)
  // print [1, 2, 3].middleOrNull()
}

Sample solution

main.dart
extension ListMiddle<T> on List<T> {
  T? middleOrNull() => isEmpty ? null : this[length ~/ 2];
}

void main() {
  print([1, 2, 3].middleOrNull());
}

Expected output

2

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 What does a generic extension provide?

  • Function only for int
  • Function only for String
  • Type-safe multi-type function Correct answer
  • Runtime type checking

Explanation: a generic extension works type-safely with multiple types.

2 Match the generic extension parts

Term Meaning
<T> Type parameter
on List<T> Target type
T? Nullable return
first First element

3 A generic extension declaration

Question
extension ListFirst<____> on List<T> {
  T? firstOrNull() => isEmpty ? null : first;
}
Answer
extension ListFirst<T> on List<T> {
  T? firstOrNull() => isEmpty ? null : first;
}

Explanation: extension ListFirst<T> takes a generic type parameter.

All lessons in Expert