Files
flutter-study-notebook/study_guide/Extension Methods in Dart.md
T

2.2 KiB

Extension Methods in Dart: A Comprehensive Guide

Extension methods allow you to add new functionality to existing libraries or classes without modifying their source code.

1. Creating an Extension

To create an extension, use the extension keyword followed by the extension name and the type you're extending.

Example:

extension StringExtension on String {
  String capitalize() {
    return '${this[0].toUpperCase()}${this.substring(1)}';
  }
}

2. Using an Extension

Once defined, you can use the extension method as if it were a part of the original class.

Example:

void main() {
  String name = 'john';
  print(name.capitalize()); // Prints: John
}

3. Extension on Built-in Types

You can add extensions to any type, including built-in types like int or List.

Example:

extension IntExtension on int {
  bool isEven() => this % 2 == 0;
}

extension ListExtension<T> on List<T> {
  T getRandomElement() => this[DateTime.now().microsecond % length];
}

void main() {
  print(42.isEven()); // Prints: true
  
  var fruits = ['apple', 'banana', 'orange'];
  print(fruits.getRandomElement()); // Prints a random fruit
}

4. Naming Conflicts

If there's a naming conflict, you can use the hide keyword to resolve it.

Example:

extension MyStringExtension on String {
  bool isLong() => length > 10;
}

extension AnotherStringExtension on String {
  bool isLong() => length > 20;
}

void main() {
  String text = 'Hello, World!';
  
  // Use specific extension
  print(MyStringExtension(text).isLong()); // Prints: true
  print(AnotherStringExtension(text).isLong()); // Prints: false
  
  // Or hide one extension
  import 'my_extensions.dart' hide MyStringExtension;
}

5. Static Extension Methods

You can also define static extension methods.

Example:

extension NumberParsing on String {
  static int parseInt(String input) => int.parse(input);
}

void main() {
  print(NumberParsing.parseInt('42')); // Prints: 42
}

Conclusion

Extension methods provide a clean way to add functionality to existing types without modifying their source code. They are particularly useful when working with types from external libraries or core Dart types that you can't modify directly.