Menu
Coddy logo textTech

Generic Methods

Part of the Object Oriented Programming section of Coddy's Dart journey — lesson 66 of 110.

Just as classes can be generic, individual methods can also have their own type parameters. This is useful when you need a flexible method without making the entire class generic.

A generic method declares its type parameter before the return type:

T findFirst<T>(List<T> items) {
  return items.first;
}

void main() {
  var firstNumber = findFirst<int>([1, 2, 3]);
  var firstWord = findFirst<String>(['hello', 'world']);
  
  print(firstNumber);  // 1
  print(firstWord);    // hello
}

Dart can often infer the type from the arguments, so you don't always need to specify it explicitly:

var result = findFirst([10, 20, 30]);  // Dart infers int

Generic methods are particularly useful inside classes when only certain operations need type flexibility:

class Printer {
  void printItem<T>(T item) {
    print('Printing: $item');
  }
  
  List<T> duplicate<T>(T item, int count) {
    return List.filled(count, item);
  }
}

void main() {
  var printer = Printer();
  printer.printItem<String>('Hello');
  printer.printItem(42);  // Type inferred as int
  
  var copies = printer.duplicate('Hi', 3);
  print(copies);  // [Hi, Hi, Hi]
}

Generic methods give you fine-grained control over type safety at the method level, keeping your classes simpler while still benefiting from compile-time type checking.

challenge icon

Challenge

Easy

Let's build a data transformation utility that showcases the power of generic methods. You'll create a Transformer class with methods that can work with any type, giving you flexibility without making the entire class generic.

You'll organize your code into two files:

  • transformer.dart: Create a Transformer class with these generic methods:
    • T getFirst<T>(List<T> items) - returns the first element from a list
    • T getLast<T>(List<T> items) - returns the last element from a list
    • List<T> repeat<T>(T item, int times) - creates a list containing the item repeated the specified number of times
    • void printPair<A, B>(A first, B second) - prints two values in the format Pair: [first] and [second]
  • main.dart: Import your transformer file and demonstrate each generic method with different types:
    • Create a Transformer instance
    • Use getFirst on [10, 20, 30] and print the result
    • Use getFirst on ['apple', 'banana', 'cherry'] and print the result
    • Use getLast on [1.5, 2.5, 3.5] and print the result
    • Use repeat to create a list of 'Hi' repeated 4 times and print the result
    • Use repeat to create a list of 7 repeated 3 times and print the result
    • Use printPair with 'Name' and 42
    • Use printPair with 100 and true

Notice how each method declares its own type parameter(s), allowing the same Transformer object to work with integers, strings, doubles, and booleans - all with full type safety. The printPair method demonstrates using two type parameters in a single method.

Expected output:

10
apple
3.5
[Hi, Hi, Hi, Hi]
[7, 7, 7]
Pair: Name and 42
Pair: 100 and true

Cheat sheet

Generic methods declare type parameters before the return type, allowing individual methods to be flexible without making the entire class generic:

T findFirst<T>(List<T> items) {
  return items.first;
}

Dart can infer the type from arguments, so explicit type specification is optional:

var result = findFirst([10, 20, 30]);  // Dart infers int

Generic methods can be used inside non-generic classes:

class Printer {
  void printItem<T>(T item) {
    print('Printing: $item');
  }
  
  List<T> duplicate<T>(T item, int count) {
    return List.filled(count, item);
  }
}

Methods can declare multiple type parameters:

void printPair<A, B>(A first, B second) {
  print('Pair: $first and $second');
}

Try it yourself

import 'transformer.dart';

void main() {
  // Create a Transformer instance
  var transformer = Transformer();

  // TODO: Use getFirst on [10, 20, 30] and print the result

  // TODO: Use getFirst on ['apple', 'banana', 'cherry'] and print the result

  // TODO: Use getLast on [1.5, 2.5, 3.5] and print the result

  // TODO: Use repeat to create a list of 'Hi' repeated 4 times and print it

  // TODO: Use repeat to create a list of 7 repeated 3 times and print it

  // TODO: Use printPair with 'Name' and 42

  // TODO: Use printPair with 100 and true
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming