În lecția despre metodele de extensie, am aflat că acestea sunt un mod frumos de a adăuga funcționalitate suplimentară tipurilor deja existente, și am făcut acest lucru prin adăugarea unei metode statice într-o clasă statică, care a luat un parametru de tip, prefixat de cuvântul cheie this, astfel:
Deci, deși clasa mea originală Carte nu conține o metodă numită VindeExemplar(), pot să o apelez în metoda Main() deoarece am declarat o metodă de extensie pentru clasa Carte, iar această metodă statică VindeExemplar() a luat un parametru de tip Carte prefixat de cuvântul cheie this, care semnalează compilatorului că metoda este intenționată ca o metodă de extensie pentru tipul Carte.
Dar de ce cuvântul cheie this? Ce înseamnă, ce reprezintă?
Să recreăm exemplul de mai sus, fără a utiliza o metodă de extensie:
Vizualizează schimbări cod Acum, când instanțiez o nouă
Carte în metoda mea
Main(), gândiți-vă la ce trebuie să facă operatorul
new: trebuie să meargă pe memoria Heap și să aloce suficientă memorie RAM pentru o
Carte. Ei bine… cât de mare este o
Carte? Dacă ne uităm în interiorul ei, putem vedea că fiecare
Carte are propria copie a câmpurilor
copiiVandute și
titluCarte. Dacă le-am declara ca fiind statice, acestea ar fi împărtășite între toate instanțele de tip
Carte, dar nu am făcut-o. Deci, în realitate, o
Carte are dimensiunea unui
int plus dimensiunea unui
string. S-ar putea să vă întrebați despre dimensiunea suplimentară ce trebuie alocată pentru metoda
VindeExemplar() a fiecărei instanțe de
Carte, însă iată pontul zilei: TOATE METODELE DIN C# SUNT STATICE. Chiar și cele de instanță, unde nu plasăm cuvântul cheie
static pe ele, doar arată ca metode de instanță! Acest lucru se datorează faptului că nu are niciun sens pentru compilator când spun
new Carte() să facă de fapt o copie a metodei
VindeExemplar(), deoarece codul din interiorul acesteia este identic pentru orice instanță de tip
Carte. Nu se schimbă de la instanță la instanță. Vă voi demonstra acest lucru, dar înainte de asta, trebuie să știți că în metodele de instanță, compilatorul vă oferă implicit cuvântul cheie
this pentru fiecare membru nestatic pe care îl folosiți. Deci, da, putem scrie metoda
VindeExemplar() astfel: dar compilatorul va adăuga implicit cuvântul cheie
this la toți membrii non-statici folosiți în interiorul acesteia: Dar acum, vom prelua controlul de la compilator și vom transforma
VindeExemplar() dintr-o metodă de instanță într-una statică. Desigur, din lecția membrii statici știm deja că nu putem accesa membri de tip instanță în cadrul metodelor statice, așa că trebuie să trimitem și un parametru de tip
Carte la metoda
VindeExemplar(), pentru a ști la care
Carte ne referim : Vizualizează schimbări cod Evident, în cadrul metodei
Main() nu mai pot apela sintactic metoda
VindeExemplar() în același mod, trebuie să o apelez prin intermediul clasei în sine, deoarece aparține schiței clasei, nu copiilor sale. Rezultatul este același: Deci, sunt doar mai explicită, în loc să mă bazez pe compilator pentru a transmite această instanță, ofer instanța eu însămi. Și din moment ce fiecare instanță
Carte are propria copie a membrilor non-statici
copiiVandute și
titluCarte, dacă ofer instanțe diferite de
Carte ca parametri la metoda statică
VindeExemplar(), fiecare dintre aceste instanțe va avea copia sa de
copiiVandute incrementată, independent una de alta. Pot să creez o altă instanță de tip
Carte, să o vând prin aceeași metodă statică și să am în continuare rezultate individuale: Vizualizează schimbări cod Dacă execut codul acum: observați cum cartea „Cei trei muschetari” are propria copie de
copiiVandute, care este incrementată separat. Deci, sper că face sens: toate metodele sunt într-adevăr statice, compilatorul doar adaugă cuvântul cheie
this pentru noi. Cu toate acestea, trebuie să recunoașteți, sintaxa pentru vânzarea unei cărți în acest caz nu este chiar frumoasă, pentru că trebuie să spunem
Carte.VindeExemplar(primaCarte), în loc să spunem doar
primaCarte.VindeExemplar(). Iar aceasta este frumusețea metodelor de extensie, de fapt, acesta este motivul pentru care spunem
this Carte în parametrii metodelor de extensie, acesta este motivul pentru care proiectanții limbajului C# au decis să folosească
this, deoarece, într-adevăr, acesta este argument
this pe care i-l dăm. Dacă modific codul pentru a converti metoda
VindeExemplar() într-o metodă de extensie, în continuare pot apela
VindeExemplar() ca și cum ar fi o metodă de instanță: Vizualizează schimbări cod
Tags: linq, membrii statici, metode, metode extensie, this
Legendă:
Legendă:
Legendă:
Legendă:
Arată ca o metodă de instanță, se simte ca o metodă de instanță, dar este într-adevăr doar o metodă statică. Iar metodele de instanță fac același lucru, în fundal.