flutter
/

Dart Extension Methods – Adding Functionality to Existing Types

Last Sync: Today

On this page

9
0%
5 min read
Remaining
5 minleft

Click any section to jump — progress syncs automatically

flutter

Dart Extension Methods – Adding Functionality to Existing Types

What are Extension Methods?

Extension methods allow you to add new functionality to existing libraries and types without creating a subclass or modifying the original source. This is especially useful when you want to enhance built‑in types like String, List, or int with your own utility methods. Extensions were introduced in Dart 2.7 and have become a powerful tool for making code more expressive and reusable.

Basic Syntax

An extension is declared with the extension keyword followed by a name and the on clause specifying the type being extended. Inside the extension body, you define methods (and optionally getters, setters, operators).

DARTRead-only
1
extension NumberParsing on String {
  int parseInt() {
    return int.parse(this);
  }

  double parseDouble() {
    return double.parse(this);
  }
}

void main() {
  var number = '42';
  print(number.parseInt()); // 42
  print('3.14'.parseDouble()); // 3.14
}

Extension with Generics

You can define extensions on generic types, which is very useful for collections. The type parameter is declared after the extension name.

DARTRead-only
1
extension ListExtensions<T> on List<T> {
  T get second {
    if (length < 2) throw RangeError('List must have at least 2 elements');
    return this[1];
  }

  List<T> reversedList() {
    return reversed.toList();
  }
}

void main() {
  var numbers = [1, 2, 3];
  print(numbers.second); // 2
  print(numbers.reversedList()); // [3, 2, 1]
}

Adding Getters and Setters

Extensions can also define getters and setters, making them feel like native properties.

DARTRead-only
1
extension StringExtensions on String {
  bool get isEmail {
    return RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(this);
  }

  String get capitalized =>
      isEmpty ? this : this[0].toUpperCase() + substring(1);
}

void main() {
  print('user@example.com'.isEmail); // true
  print('hello'.capitalized); // Hello
}

Extension Operators

You can define operators inside extensions, enabling custom behavior with existing operators.

DARTRead-only
1
extension IntExtensions on int {
  int operator [](int index) {
    return this >> (index * 8) & 0xFF;
  }
}

void main() {
  int value = 0x12345678;
  print(value[0]); // 0x78 (least significant byte)
  print(value[1]); // 0x56
}

Static Methods and Fields

Extensions cannot have static fields, but they can have static helper methods. However, static members are not accessed via the extended instance; they are called on the extension name itself.

DARTRead-only
1
extension StringHelpers on String {
  static String repeat(String s, int count) {
    return s * count;
  }
}

void main() {
  print(StringHelpers.repeat('ha', 3)); // hahaha
}

Conflicts and Resolution

If multiple extensions define the same method name for the same type, Dart uses the closest import or the one explicitly specified. You can also qualify the extension to resolve ambiguity.

DARTRead-only
1
extension A on String {
  void foo() => print('A');
}

extension B on String {
  void foo() => print('B');
}

void main() {
  // If both extensions are imported, call via extension name
  'test'.A.foo(); // A
  'test'.B.foo(); // B
}

Extending Nullable Types

You can also write extensions on nullable types (using ?). This allows you to call methods safely on potentially null values.

DARTRead-only
1
extension NullableStringExtensions on String? {
  bool get isNullOrEmpty => this == null || this!.isEmpty;

  String orDefault(String defaultValue) => this ?? defaultValue;
}

void main() {
  String? maybeNull;
  print(maybeNull.isNullOrEmpty); // true
  print(maybeNull.orDefault('Default')); // Default
}

Key Takeaways

    • Extensions add new functionality to existing types without subclassing.
    • Use extension Name on Type syntax.
    • Extensions can define methods, getters, setters, and operators.
    • Generic extensions work with collection types.
    • Extensions can be qualified to resolve naming conflicts.
    • They are a great way to keep code clean and expressive.

Try it yourself

extension StringExtensions on String {
  bool get isPalindrome {
    String cleaned = replaceAll(RegExp(r'\s+'), '').toLowerCase();
    return cleaned == cleaned.split('').reversed.join();
  }
}

void main() {
  print('racecar'.isPalindrome); // true
  print('hello'.isPalindrome);   // false
}

Test Your Knowledge

Q1
of 4

What keyword is used to declare an extension in Dart?

A
extend
B
extension
C
with
D
on
Q2
of 4

Can an extension add instance fields to a class?

A
Yes
B
No
C
Only if the class is not final
D
Only with the `field` keyword
Q3
of 4

How do you define a generic extension for List?

A
extension ListExtensions on List {}
B
extension ListExtensions<T> on List<T> {}
C
extension ListExtensions<T> extends List<T> {}
D
extension ListExtensions<T> implements List<T> {}
Q4
of 4

If two extensions define the same method name for the same type, how can you call a specific version?

A
By the order of imports
B
By using the extension name as a prefix: `'str'.MyExtension.method()`
C
By using the `as` keyword
D
It's impossible

Frequently Asked Questions

Can I add fields to a class with extensions?

No, extensions cannot add instance fields. They can only add methods, getters, setters, and operators. If you need state, consider a subclass or a wrapper class.

Do extensions override existing methods?

No. If an extension defines a method with the same name as an existing instance method, the instance method takes precedence. Extensions cannot override built‑in methods.

Can I use extensions on null?

Yes, by writing an extension on a nullable type (e.g., extension X on String?). Then you can call the extension methods on nullable instances without explicit null checks.

How do I import an extension?

Extensions are imported like any other Dart code. If the extension is in a separate file, import that file. The extension's methods become available automatically on the extended type within that scope.

Can I have private extension members?

Yes, you can prefix members with _ to make them private to the library, just like regular class members.

Previous

dart generics

Next

dart typedef

Related Content

Need help?

Explore our comprehensive docs or start a chat with our tech experts.