DEV Community

Michele Volpato
Michele Volpato

Posted on • Edited on • Originally published at ishouldgotosleep.com

2 1

Extension methods for generic types

Since Dart 2.7 it is possible to add functionalities to existing libraries. If a class is missing a method you would like to use, you can just extend that class with your own implementation of such a method.

You do not need to create a pull request on the code of the library you want to update, you can keep the new functionality locally to your code. For example, if you need to format a Duration so that it shows days, hours, minutes, and seconds in the following format: dd:HH:MM:SS, you can define an extension method on Duration:

extension DurationFormatter on Duration {
  /// Returns a day, hour, minute, second string representation of this `Duration`.
  ///
  ///
  /// Returns a string with days, hours, minutes, and seconds in the
  /// following format: `dd:HH:MM:SS`. For example,
  ///
  ///   var d = new Duration(days:19, hours:22, minutes:33);
  ///    d.dayHourMinuteSecondFormatted();  // "19:22:33:00"
  String dayHourMinuteSecondFormatted() {
    this.toString();
    return [
      this.inDays,
      this.inHours.remainder(24),
      this.inMinutes.remainder(60),
      this.inSeconds.remainder(60)
    ].map((seg) {
      return seg.toString().padLeft(2, '0');
    }).join(':');
  }
}

void main() {
  var d = Duration(days:19, hours:22, minutes:33);
  print(d.dayHourMinuteSecondFormatted()); // 19:22:33:00
}
Enter fullscreen mode Exit fullscreen mode

Extension on generic types

You can not only extend a "concrete" type like Duration. You can also extend the functionalities of a generic type, so that all its concrete instances (and all subclasses) obtain the new extension method.

For instance, if we want to add a firstWhereOrNull to List, where we either return the first element in the list that satisfies a condition, or null if none satisfies that condition, we can create an extension method like this:

extension FirstWhereOrNull<E> on Iterable<E> {
  /// Returns the first element that satisfies the given predicate test.
  ///
  /// Iterates through elements and returns the first to satisfy test.
  /// If none is found, returns `null`.
  E? firstWhereOrNull(bool test(E element)) {
    for (E element in this) {
      if (test(element)) return element;
    }
    return null;
  }
}

void main() {
  final List<String> myList = ["First", "Second", "Third"];

  print(myList.firstWhereOrNull((element) => 
     element.endsWith('d'))); // Second

  print(myList.firstWhereOrNull((element) => 
     element.startsWith('d'))); // null
}
Enter fullscreen mode Exit fullscreen mode

By creating the extension method on the generic Iterable<E> we add it to all concrete types of all subclasses of Iterable, like Queue, List, and Set, thus also to List<E>.

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

Top comments (0)

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay