Colecțiile sunt un concept important în POO, iar suportul complet pentru colecții în C# este unul dintre cele mai bune ale limbajului.
De ce să folosești seturi generice? Înainte de C# 2.0, colecțiile puteau fi implementate în două moduri principale: a. Folosirea ArrayList Introducerea obiectelor direct în ArrayList este intuitivă, dar pentru că elementele din colecție sunt de tip Object, trebuie să faci conversie de tip plictisitoare de fiecare dată când o folosești. b. Folosirea claselor de colecție personalizate O practică comună este să se moștenească o clasă personalizată din clasa abstractă CollectionBase și să se implementeze o colecție de tipuri puternice prin încapsularea obiectului IList. Această metodă necesită scrierea unei clase personalizate corespunzătoare pentru fiecare tip de colecție, ceea ce este multă muncă. Apariția colecțiilor generice rezolvă bine problemele de mai sus, iar o singură linie de cod poate fi folosită pentru a crea un set de un anumit tip. Ce este genericul? Genericele sunt elemente noi în C# 2.0 (numite șabloane în C++) care sunt folosite în principal pentru a rezolva o serie de probleme similare. Acest mecanism permite ca numele clasei să fie transmis ca argument către tipul generic și să fie generat obiectul corespunzător. Poate fi mai bine să privim genericele (inclusiv clase, interfețe, metode, delegați etc.) ca șabloane, unde partea variantă este înlocuită cu numele clasei transmis ca argument, rezultând o nouă definiție a tipului. Genericul este un subiect relativ amplu și nu îl voi analiza în detaliu aici, iar cei interesați pot consulta informațiile relevante. Cum pot crea o colecție generică? Clasa generică List din spațiul de nume System.Collections.Generic <T>este folosită pentru a crea colecții, iar sintaxa este următoarea: [mw_shl_code=csharp,adevărat] <T> List ListOfT = new List<T>(); [/mw_shl_code] "T" este tipul care trebuie folosit, care poate fi tip simplu, cum ar fi string, int sau tipuri definite de utilizator. Să vedem un exemplu concret.
Clasa Person este definită astfel: [mw_shl_code=csharp,true]clasa Persoană
{ _name de coadă privată; Nume Private Int _age; Vârstă
Creează un obiect Person public Person (nume șir, int vârstă) { this._name= Nume; this._age = Vârstă; }
Nume Nume de coardă publică { get { return _name; } }
Vârstă public int Age { get { return _age; } }
}
//创建Person对象 Persoana p1 = Persoană nouă ("Zhang San", 30); Persoana p2 = Persoană nouă ("Li Si", 20); Persoana p3 = persoană nouă ("Wang Wu", 50);
//创建类型为Person的对象集合 Persoane de pe<Person> listă = nouă <Person>Listă();
//将Person对象放入集合 persoane. Add(p1); persoane. Add(p2); persoane. Add(p3);
//输出第2个人的姓名 Console.Write(persons[1]. Nume); [/mw_shl_code] După cum puteți vedea, colecțiile generice simplifică mult codul de implementare al colecțiilor, prin care puteți crea cu ușurință colecții de tipuri specificate. Nu doar atât, dar colecțiile generice oferă și funcții mai puternice, hai să aruncăm o privire la sortarea și căutarea din ele. Sortarea colecțiilor generice Sortarea se bazează pe comparație, iar pentru a sorta trebuie mai întâi să compari. De exemplu, dacă există două numere 1 și 2, pentru a le sorta, trebuie mai întâi să comparăm aceste două numere și să le sortăm conform rezultatelor comparației. Dacă vrei să compari obiecte, situația este puțin mai complicată, de exemplu, dacă compari obiecte Persoană, poți compara după nume sau vârstă, ceea ce necesită determinarea regulilor de comparație. Un obiect poate avea mai multe reguli de comparație, dar doar o singură regulă implicită, care este plasată în clasa ce definește obiectul. Regulile implicite de comparație sunt definite în metoda CompareTo, care aparține <T>interfeței generice IComparable. Vezi codul de mai jos: [mw_shl_code=csharp,true]clasa Persoană :IComparabil<Person>
{ Compară după vârstă public int CompareTo(Person p) { Returnează asta. Vârstă - p.Vârstă; } }[/mw_shl_code] Parametrii metodei CompareTo sunt un alt obiect de același tip cu care trebuie comparat, valoarea de returnare este de tip int, dacă valoarea returnată este mai mare decât 0, înseamnă că primul obiect este mai mare decât al doilea, dacă valoarea de returnare este mai mică decât 0, înseamnă că primul obiect este mai mic decât al doilea, iar dacă returnează 0, cele două obiecte sunt egale. După definirea regulilor implicite de comparare, poți sorta colecția folosind metoda Sort fără parametri, după cum urmează: [mw_shl_code=csharp,true]// Sortează colecția conform regulilor implicite persoane. Sort();
//输出所有人姓名 foreach (Persoana p în persoane)
{ Console.WriteLine(p.Name); Ordinea de ieșire este "Li Si", "Zhang San" și "Wang Wu" }[/mw_shl_code] În practică, este adesea necesar să sortăm colecția conform unei varietăți de reguli diferite, ceea ce necesită definirea altor reguli de comparație, care pot fi definite în metoda Compare, care aparține <T>interfeței generice IComparer, vă rugăm să consultați următorul cod: [mw_shl_code=csharp,true]clasă NumeComparator : IComparer<Person>
{ Instanțe de secvențiere de stocare public static NameComparer Default = new NameComparer();
Compară după nume public int Compare(Person p1, Person p2) { return System.Collections.Comparer.Default.Compare(p1. Nume, p2. Nume); } }[/mw_shl_code] Parametrii metodei Compare sunt două obiecte de același tip care urmează a fi comparate, iar valoarea returnată este de tip int, iar regulile de procesare a valorilor returnate sunt aceleași ca cele ale metodei CompareTo. Comparer.Default returnează un obiect Comparer încorporat pentru compararea a două obiecte de același tip. Iată cum să sortezi colecția cu acest comparator nou definit: [mw_shl_code=csharp,true]//Sortează colecția după nume persoane. Sort(NameComparer.Default);
//输出所有人姓名 foreach (Persoana p în persoane)
{ Console.WriteLine(p.Name); Ordinea de ieșire este "Li Si", "Wang Wu" și "Zhang San" }[/mw_shl_code] Poți, de asemenea, să sortezi colecția delegând, în primul rând, să definești o metodă pe care delegatul să o cheme pentru a stoca regulile de comparație și poți folosi o metodă statică. Vezi codul de mai jos: [mw_shl_code=csharp,true]clasa Comparație
{ Compară după nume public static int Nume (Persoană p1, Persoană p2) { return System.Collections.Comparer.Default.Compare(p1. Nume, p2. Nume); } }[/mw_shl_code] Parametrii metodei sunt două obiecte de același tip care trebuie comparate, valoarea de returnare este de tip int, iar regula de procesare a valorii de returnare este aceeași ca cea a metodei CompareTo.Apoi sortează colecția prin sistemul generic de delegați încorporat. <T>Comparație: [mw_shl_code=csharp,adevărat] <Person> Sistem.NumeComparațieComparație = noul <Person>Sistem.Comparație(PersonComparison.Name); persoane. Sort(NameComparison);
//输出所有人姓名 foreach (Persoana p în persoane)
{ Console.WriteLine(p.Name); Ordinea de ieșire este "Li Si", "Wang Wu" și "Zhang San" }[/mw_shl_code] Se poate observa că ultimele două metode pot sorta colecția conform regulilor specificate, dar autorul preferă să folosească metoda delegării și poate lua în considerare plasarea diferitelor reguli de comparație într-o clasă și apoi apelarea lor flexibilă. Căutați colecții generice Căutarea este pentru a găsi elemente care îndeplinesc condiții specifice din colecție, iar mai multe condiții de căutare pot fi definite și apelate după necesitate. În primul rând, definiți criteriile de căutare astfel: [mw_shl_code=csharp,true]clasa PersonPredicat
{ Găsește persoane de vârstă mijlocie (peste 40 de ani) public static bool MidAge(Person p) { dacă (p.Vârstă >= 40) întoarcerea cu adevărat; altfel returnează false; } }[/mw_shl_code] Criteriile de căutare de mai sus sunt plasate într-o metodă statică cu un tip de returnare booleană, iar elementele din colecție care îndeplinesc anumite condiții returnează true, altfel false.Apoi caută colecția prin sistemul generic de delegate integrat. <T>Predicat: [mw_shl_code=csharp,adevărat] System.Predicat<Person> MidAgePredicat = noul <Person>Sistem.Predicat(PersonPredicate.MidAge); <Person> Listă Persoane de vârstă mijlocie = persoane. FindAll (PredicateMidAge);
//输出所有的中年人姓名 foreach (Persoana p în MidAgePersons)
{ Console.WriteLine(p.Name); Ieșire "Wang Wu" }[/mw_shl_code] Extinderea colecțiilor generice Ce se întâmplă dacă vrei să obții numele tuturor persoanelor din set, separate printr-o virgulă? Având în vedere că funcționalitatea pe care o poate oferi o singură clasă este limitată, este firesc să ne gândim <T>la extinderea clasei List, care este și ea o clasă și, prin urmare, poate fi extinsă prin moștenire. Vezi codul de mai jos: [mw_shl_code=csharp,true]// Definiți clasa colecției Persoane Clasă Persoane: Listă<Person>
{ Află numele tuturor celor din colecție șirul public GetAllNames() { dacă (asta. Numără == 0) întoarcerea "";
string val = ""; foreach (Persoana p aici) { val += p.Name + ","; }
Întoarce-te, Val. Substring(0, val. Lungime - 1); }
}
//创建并填充Persons集合 Persoane PersonCol = Persoane Noi(); PersonCol.Add(p1); PersonCol.Add(p2); PersonCol.Add(p3);
//输出所有人姓名 Console.Write(PersonCol.GetAllNames()); Ieșire "Zhang San, Li Si, Wang Wu"[/mw_shl_code] Rezumat: Acest articol se concentrează pe utilizarea genericelor în C# 2.0 pentru implementarea colecțiilor, precum și pentru extinderea funcției de colectare, iar utilizarea corectă a colecțiilor generice poate reduce multă duplicare a muncii și poate îmbunătăți semnificativ eficiența dezvoltării. De fapt, seturile sunt doar o aplicație tipică a genericelor, iar dacă vrei să afli mai multe despre generice, poți consulta și alte materiale relevante. Sper că acest articol ți-a fost de folos :-)
|