Nivelul de acces la date: Expunerea la lista <>: idee proastă?

În prezent, codifică un simplu strat de acces la date și mă întrebam ce tip trebuie să expun celorlalte straturi.

I am going to internally implement the Data as a List<>, but I remember reading something about not exposing the List type to the consumers if not needed.

public List GetAllUsers()//non C# users: that means List of User :)

Știți de ce (google nu a ajutat)? Ce vă expuneți de obicei pentru astfel de lucruri? IList? IEnumerable?

3

3 răspunsuri

Usually it's best to expose the least powerful interface that the user can still meaningfully work with. If the user just needs some enumerable data, return IEnumerable. If that's not enough because the user needs to be able to modify the list (attention! shouldn't often be the case), return an IList.

/EDITAȚI | ×:

Joel întreabă o întrebare validă în comentariul său: De ce, într-adevăr, expuneți interfața cea mai puțin puternică în locul acordării puterii maxime a utilizatorului? (Parafrazat)

Ideea din spatele acestui lucru este că metoda returnând datele ar putea să nu se aștepte ca utilizatorul să-și modifice conținutul: O altă metodă a clasei ar putea aștepta ca lista să nu fie goală după ce o referință la ea a fost returnată. Imaginați-vă că utilizatorul elimină toate datele din listă. Cealaltă metodă trebuie să facă o verificare suplimentară, care ar putea să nu fie necesară.

Mai important, acest lucru expune părți din implementarea internă prin intermediul tipului de returnare. Dacă am nevoie să modificăm implementarea în viitor, astfel încât să nu mai folosească un container IList , am o problemă: fie trebuie să schimb contractul de metode, introducând o schimbare de performanță. Sau trebuie să copiez datele într-un container.

Ca exemplu, imaginați-vă că o implementare eficientă utilizează un Dicționar și returnează colecția Values ​​ care nu implementează IList .

6
adăugat
De asemenea, aveți opțiunea de a reveni la ReadOnlyCollection atunci când doriți să controlați acest lucru pe partea de apel.
adăugat autor CVertex, sursa
Nu am cumpărat încă ideea "cel mai puțin puternic"; ce zici de a face fiecare bloc de cod cât mai util posibil?
adăugat autor Joel Coehoorn, sursa

Cu siguranta este ceva Ceva. Folosind o interfață veți reduce cuplarea și veți face mai ușor schimbarea detaliilor implementării stratului de date pe drum. Care interfață depinde de circumstanțe. IList este bun, dar uneori este posibil să aveți nevoie de funcționalitate ICollection sau doriți să specificați valori care sunt ReadOnly.

3
adăugat

Ar trebui să vă gândiți cu atenție înainte de a reveni la IEnumerable. Dacă codul de bază utilizează "randament" pentru a genera IEnumerable sau folosește LINQ, atunci veți ține în evidență toate resursele utilizate.

Ar trebui să copiați IEnumerable într-un alt IEnumerable înainte de ao returna. Folosind IList, faceți acest lucru o cerință, astfel încât nimeni să nu poată întoarce din greșeală un IEnumerable.

Pe de altă parte, întoarcerea unui IList implică apelantului că poate schimba lista returnată.

2
adăugat
Buna observatie. Poate că ați putea adăuga un exemplu care să ilustreze un astfel de caz pentru binele lui.
adăugat autor Konrad Rudolph, sursa