Ce face extension
O extensie adaugă funcționalitate unui tip pe care nu-l poți schimba: String, int, List sau clase din alte pachete. După extension TextRo on String { ... } poți scrie 'ana'.capitalizat ca și cum metoda ar fi fost acolo de la început.
În corpul extensiei, this (sau simplu numele membrilor) se referă la valoarea pe care este apelată metoda. Extensiile pot avea metode, getter-e, setter-e, operatori și membri static, dar nu câmpuri de instanță.
Extensiile sunt rezolvate după tipul static al variabilei, la compilare. Pe o valoare dynamic nu funcționează. Ca să fie folosită în alt fișier, extensia trebuie să aibă nume și să fie importată.
Exemple
Exemplul 1: Metode noi pentru String
Extensia adaugă un getter și o metodă oricărui String.
extension TextRo on String {
String get capitalizat => isEmpty ? this : this[0].toUpperCase() + substring(1).toLowerCase();
String faraDiacritice() {
const din = 'ăâîșțĂÂÎȘȚ';
const in_ = 'aaistAAIST';
return split('').map((c) {
final i = din.indexOf(c);
return i == -1 ? c : in_[i];
}).join();
}
}
void main() {
print('bUCUREȘTI'.capitalizat);
print('Târgu Mureș, Piatra Neamț'.faraDiacritice());
}
Rezultat
București
Targu Mures, Piatra Neamt
Exemplul 2: Extensie pentru numere
lei formatează un num ca preț; funcționează pentru int și double.
extension Pret on num {
String get lei => '${toStringAsFixed(2).replaceAll('.', ',')} lei';
num cuReducere(int procent) => this * (100 - procent) / 100;
}
void main() {
print(49.9.lei);
print(120.lei);
print(120.cuReducere(15).lei);
}
Rezultat
49,90 lei
120,00 lei
102,00 lei
Exemplul 3: Extensie generică pe liste
media apare pe orice List de numere, iar alDoilea pe orice listă.
extension Statistici on List<num> {
double get media => isEmpty ? 0 : fold<double>(0, (s, x) => s + x) / length;
}
extension Elemente<T> on List<T> {
T? get alDoilea => length > 1 ? this[1] : null;
}
void main() {
final note = [9, 7, 10, 8];
print('Media: ${note.media}');
print(['Ana', 'Bianca'].alDoilea);
print(<String>['singur'].alDoilea);
}
Rezultat
Media: 8.5
Bianca
null
Greșeli frecvente
- Apelul unei metode din extensie pe o valoare
dynamic:NoSuchMethodErrorla rulare, pentru că extensiile se aleg după tipul static. - Câmpuri de instanță într-o extensie: nu sunt permise (
Extensions can't declare instance fields). - Două extensii importate cu aceeași metodă pentru același tip: conflict. Ascunde una cu
hidesau apelează explicitTextRo('ana').capitalizat.
Comenzi înrudite
extension type: Un tip nou, verificat la compilare, care la rulare este doar o valoare existentă (de ex. un int), fără cost.generics: Clase și funcții cu tipuri ca parametri (<T>), care funcționează la fel pentru orice tip, păstrând verificarea tipurilor.operator: Definește ce fac operatorii (+, -, ==, [], < etc.) pentru obiectele unei clase.import: Face disponibile în fișierul curent numele publice ale altei biblioteci: din SDK, dintr-un pachet sau din proiect.