Extension Methods
Learn to extend a core-class or a third-party's functionalities using Extension Methods.
We'll cover the following
Introduction
Dart Extensions were first introduced in Dart 2.6 as a preview but they have been officially released in Dart 2.7. The extensions feature helps to add functionality to existing libraries.
Sometimes you may want to add utility method(s) in a third-party library or in a core class like String for your convenience. However, it is not always possible to add your methods in those classes.
One possible solution is to write utility and/or wrapper classes with static
methods and members. But the downside to this approach is that these extra classes can bloat your codebase and increase the number of objects.
In such scenarios, the extensions feature is useful. It may appear like wrapper classes, but they are different. In wrapper classes, the object is explicitly passed as an argument to the static methods; however, extensions implicitly extend the type.
Defining Extensions
In Dart, extensions are defined inside one code block. The code block begins with extension
followed by an optional name for the extension, the on
keyword, and the data type.
Let’s add custom functionality to the List
data type. We can utilize the generic type T
to support different varieties of data types.
Do not worry if you are unfamiliar with generics. We will discuss generics in detail later on in the course.
There are two options for writing the extension code block.
//Option #1
extension<T> on List<T> {}
//Option #2
extension<T> MyList on List<T> {}
Option #1 is the logical avenue when extensions are defined in the same file as they are intended to be used. The same extension can be defined in another way. See Option #2.
In Option #2, the extension is named MyList
. It is optional to name the extension. Option #2 is a better choice when extensions are written in a separate file or in the library. It is also a better choice when extensions and are being imported into another Dart file.
Types of Extension
Dart supports three types of extension implementations:
- Extension Methods
- Extension Operators
- Extension Properties
extension<T> on List<T> {
//extension methods
//extension operators
//extension properties
}
In this lesson, we will explore Extension Methods.
Extension Methods
In this section, we will add two extension methods for the List
data type. With the given List
of prices, we will apply it to both examples. In the first example, we will learn to write an extension method for List
with the help of a very trivial example. In the second example, we’ll modify the list items with the help of the extension method.
Example #1
In this example, you will learn to write an extension method for the List
data type. The extension method priceList()
returns the price listing in the same condition. This method demonstrates how extensions implicitly extend the type using this
.
//Local extension methodextension<T> on List<T> {//Extension Method demonstrationList<T> priceList() => this.map((item) => item).toList();}void main() {//List of pricesList prices = [1, 1.99, 4];print("Price listing:");//priceList() is being called on `prices` list//and returns the list of pricesprint(prices.priceList());}
Example #2
In this example, you will learn to use the extension method to modify the list items. Let’s assume you want a method provided by the List
class to append a dollar sign ‘$’ for each price item listed. Since this functionality is specific to this example, adding it to the core List
class may not make sense. Such are the scenarios where Dart’s extensions
functionality shines. This particular method can be added to behave as if the core-class provided it.
The extension method priceLabels(String symbol)
iterates over the price listing, and appends a symbol
prefix for each price.
Now run the code snippet below to see the extension method priceLabels(...)
in action.
extension<T> on List<T> {//Extension Method: Adding $ prefixList<String> priceLabels(String symbol) =>this.map((item) => "$symbol${item}").toList();}//Let's use `priceLabels()`, and pass the '$' symbol//that we wish to be prefixed with items of list `prices`.void main() {//List of pricesList prices = [1, 1.99, 4];print("\nPrice listing with \$ prefix");//The $ symbol is passedprint(prices.priceLabels("\$"));}