Skip to Content

Generics trong Dart

1. Giới thiệu

Generics cho phép viết code linh hoạt, tái sử dụng với nhiều kiểu dữ liệu khác nhau.

2. Generic Class

class Box<T> { T value; Box(this.value); T getValue() => value; void setValue(T newValue) => value = newValue; } void main() { var intBox = Box<int>(42); var stringBox = Box<String>('Hello'); print(intBox.getValue()); // 42 print(stringBox.getValue()); // Hello }

3. Generic Function

T first<T>(List<T> items) { return items[0]; } void main() { print(first<int>([1, 2, 3])); // 1 print(first<String>(['a', 'b'])); // a // Type inference print(first([1, 2, 3])); // 1 }

4. Nhiều Type Parameters

class Pair<K, V> { K key; V value; Pair(this.key, this.value); @override String toString() => '($key, $value)'; } void main() { var pair = Pair<String, int>('age', 25); print(pair); // (age, 25) }

5. Generic với extends (Bounded)

class NumberBox<T extends num> { T value; NumberBox(this.value); T add(T other) => (value + other) as T; } void main() { var intBox = NumberBox(10); print(intBox.add(5)); // 15 var doubleBox = NumberBox(3.14); print(doubleBox.add(2.86)); // 6.0 // var stringBox = NumberBox('hello'); // Error! }

6. Generic Collections

void main() { // List<T> List<int> numbers = [1, 2, 3]; // Map<K, V> Map<String, int> ages = {'Alice': 25, 'Bob': 30}; // Set<T> Set<String> unique = {'a', 'b', 'c'}; }

7. Generic Interface

abstract class Repository<T> { T? findById(int id); List<T> findAll(); void save(T item); void delete(int id); } class UserRepository implements Repository<User> { final Map<int, User> _users = {}; @override User? findById(int id) => _users[id]; @override List<User> findAll() => _users.values.toList(); @override void save(User item) => _users[item.id] = item; @override void delete(int id) => _users.remove(id); }

8. Covariant và Contravariant

class Animal {} class Dog extends Animal {} class Cat extends Animal {} // Covariant: List<Dog> là subtype của List<Animal> void printAnimals(List<Animal> animals) { for (var animal in animals) { print(animal); } } void main() { List<Dog> dogs = [Dog(), Dog()]; printAnimals(dogs); // OK }

9. Factory với Generics

class Cache<T> { final Map<String, T> _cache = {}; T? get(String key) => _cache[key]; void set(String key, T value) => _cache[key] = value; void clear() => _cache.clear(); } void main() { var userCache = Cache<User>(); var configCache = Cache<String>(); }

📝 Tóm tắt

  • Generic type parameter
  • extends giới hạn type
  • Nhiều params: <K, V>
  • Giúp code type-safe và tái sử dụng
  • Phổ biến trong collections và repositories
Last updated on