Skip to main content

Command Palette

Search for a command to run...

Dart: Generics

Updated
3 min read
Dart: Generics

In Dart, by default collections are heterogeneous.

However, by the use of generics, we can make a collection to hold homogeneous values.

The use of Generics makes the use of a single compulsory data type to be held inside the collection. Such collections are called type-safe collections. By the use of generics, type safety is ensured in the Dart language.

Collections:

Syntax:

Collection_name <data_type> identifier= new Collection_name<data_type>

Generic List:

In Dart, a List is simply an ordered group of objects. A list is simply an implementation of an array.

main() {  
  List<int> listEx = [];  
  listEx.add(341);  
  listEx.add(1);  
  listEx.add(23);  

  // iterating across list listEx  
  for (int element in listEx) {  
     print(element);  
  }  
}

Output:
341
1
23

Generic Set:

In Dart, a Set represents a collection of objects in which each object can exist only once.

main() {  
  Set <int> SetEx = new Set <int>();  
  SetEx.add(12);  
  SetEx.add(3);  
  SetEx.add(4); 

  // Already added once, hence wont be added
  SetEx.add(3);  

  // iterating across Set SetEx  
  for (int element in SetEx) {  
     print(element);  
  }  
}
Output:
12
3
4

Generic Map:

In Dart, Map is a dynamic collection of the key, value pairs.

main() {  

  // Creating a Map with Name and ids of students
  Map <String,int> mp={'Jinali':1,'Reet':002,'Moksha':003};  
  print('Map :${mp}');  
}

Output:
Map :{Jinali: 1, Reet: 2, Moksha: 3}

Creating Generic Classes

Syntax of Generics classes:

In Dart, generics are defined using angle brackets (<>) to specify a type parameter. For example, a generic class Box<T> can hold values of any type T:

class Box<T> {
  T value;

  Box(this.value);
}

Here, T is a placeholder for the actual type that will be used when creating instances of the Box class. We can create instances of Box with specific types, such as int, String, or custom objects.

// Define a generic class Box
class Box<T> {
  T value;

  Box(this.value);

  void printValue() {
    print('Value: $value');
  }
}

void main() {
  // Create a Box for integers
  var intBox = Box<int>(10);
  intBox.printValue(); // Output: Value: 10

  // Create a Box for strings
  var stringBox = Box<String>('Hello');
  stringBox.printValue(); // Output: Value: Hello
}

In this example:

  • We define a generic class Box<T>, where T is a placeholder for the type of value the box will hold.

  • We create instances of Box with specific types (int and String) by specifying the type in angle brackets (<int> and <String>).

  • We can then use these instances to store and manipulate values of the specified types.

Generics of specified SubType

In Dart, you can specify that a generic type parameter should be a subtype of a certain type using the extends keyword. This allows you to constrain the range of types that can be used with a generic class, function, or method to only those types that are subtypes of the specified type. Here's how you can use generics with a specified subtype:

class Box<T extends num> {
  T value;

  Box(this.value);

  void display() {
    print('Value: $value');
  }
}

void main() {
  var intBox = Box<int>(10);
  intBox.display(); // Output: Value: 10

  var doubleBox = Box<double>(3.14);
  doubleBox.display(); // Output: Value: 3.14

  // This will cause a compilation error because String is not a subtype of num
  // var stringBox = Box<String>('Hello'); 
}

Output:
Value: 10
Value: 3.14

In this example, the generic class Box has a type parameter T that is constrained to be a subtype of num using extends num. This means that T can only be a type that is a subtype of num, such as int or double.

Using extends num ensures that only numeric types can be used with the Box class. If you try to instantiate Box with a type that is not a subtype of num, such as String, you'll get a compilation error.

This way, generics with specified subtypes allow you to enforce constraints on the types that can be used with your generic classes, functions, or methods, providing additional type safety and preventing potential runtime errors.

Dart

Part 26 of 50

I'll be here to provide explanations, examples, and assistance as you explore the depths of Dart programming language. Together, we'll unravel the intricacies of Dart, from its fundamental concepts to

Up next

Dart Mixins: Problems with Extending and Implementing

Dart Mixins: A Powerful Tool for Code Reuse and Composition Mixins in Dart provide a flexible mechanism for code reuse and composition by allowing classes to include behavior from multiple sources. They offer a way to share functionality across class...

More from this blog

Flutter Journey with Jinali

141 posts