Saturday, November 27, 2021 11:22

Cuprins >> LINQ > Scrierea de metode de extensie LINQ personalizate

Scrierea de metode de extensie LINQ personalizate

În lecția anterioară, în care v-am prezentat o previzualizare a modului în care arată LINQ, am terminat cu acest cod:


Și am aflat că sintaxa în formă liberă a LINQ este același lucru și cu sintaxa declarativă a LINQ, care este și ea aceealași lucru cu o grămadă de metode de extensie pentru interfața IEnumerable, declarate în interiorul unei clase numite Enumerable.

Dacă vă amintiți lecția despre metodele de extensie, spuneam acolo cum compilatorul caută mai întâi în cel mai apropiat domeniu pentru numele metodelor, și se deplasează spre exterior. Deci, cel mai apropiat domeniu pentru apelul funcției Where() din codul de mai sus este clasa Program. Dacă găsește o funcție numită Where() în interiorul său care are semnătura necesară, o folosește; dacă nu o găsește, va începe să caute codurile tuturor bibliotecilor importate în directivele using din partea de sus a fișierului, unde se uită în interiorul codurile din using System.Linq; și găsește funcția Where() în clasa statică Enumerable.

Pentru a demonstra acest lucru și pentru a risipi „magia” implicată în metodele de extensie LINQ, voi scrie propria mea versiune a funcției Where().

Deoarece funcția Where() este doar o metodă de extensie pentru interfața IEnumerable și, întrucât metodele de extensie sunt declarate numai în interiorul claselor statice, primul lucru pe care trebuie să-l fac este să fac și eu clasa Program statică. După aceea, aș putea să copiez semnătura funcției Where() din clasa Enumerable și să o fac și eu generică, dar din moment ce variabila mea numere este doar un array de tip int, voi face și eu o metodă de extensie doar pentru array-urile de tip int, pentru simplitate. Amintiți-vă, un array implementează și IEnumerable, de aceea sunt în măsură să folosesc metoda mea de extensie pentru interogările LINQ:

Vizualizează schimbări cod


Legendă:

  • liniile verzi cu un semn plus lângă numerele liniilor sunt linii noi adăugate
  • liniile rosii cu un semn minus lângă numerele liniilor sunt linii vechi șterse


Și acum, explicația: primul parametru, this int[] numere, indică doar că creăm o metodă de extensie pentru array-urile de tip int (am explicat semnificația lui this într-o lecție anterioară), în timp ce al doilea este doar un delegat de tip Func care preia un int ca parametru și returnează un bool. Restul este ușor: iterez prin toate numerele din array-ul numere și pe fiecare dintre ele le trec prin delegatul Func. Toate cele care trec, sunt returnate înapoi.

Acum, deoarece am trei moduri de a face aceleași lucruri LINQ (sintaxa în formă liberă, sintaxa declarativă și apelul de metode statice), doar primele două dintre ele vor apela de fapt versiunea mea de Where(), deoarece în a treia apelez în mod explicit funcția Where() din clasa Enumerable. Putem seta un breakpoint în funcția mea personalizată Where() și să verificăm dacă execuția îl atinge:

și putem vedea că o face. Iar rezultatul arată la fel ca în cazul funcției Where() „reale”:

Tags: , , ,

Leave a Reply



Follow the white rabbit