Kokoelmat ovat tärkeä käsite OOP:ssa, ja täysi tuki C#:n kokoelmille on yksi kielen parhaista.
Miksi käyttää geneerisiä settejä? Ennen C# 2.0:aa kokoelmat voitiin toteuttaa kahdella pääasiallisella tavalla: a. Käytä ArrayListiä Objektien laittaminen suoraan ArrayListiin on intuitiivista, mutta koska kokoelman alkiot ovat Object-tyyppiä, sinun täytyy tehdä työläs tyyppimuunnos joka kerta kun käytät sitä. b. Käytä mukautettuja kokoelmaluokkia Yleinen käytäntö on periä mukautettu luokka CollectionBase-abstraktista luokasta ja toteuttaa vahva tyyppikokoelma kapseloimalla IList-objekti. Tämä menetelmä vaatii vastaavan mukautetun luokan kirjoittamista jokaiselle kokoelmatyypille, mikä on paljon työtä. Geneeristen kokoelmien syntyminen ratkaisee yllä mainitut ongelmat hyvin, ja vain yhdellä koodirivillä voidaan luoda tietyn tyyppinen joukko. Mikä on geneerinen? Geneeriset ovat uusia elementtejä C# 2.0:ssa (C++:ssa kutsutaan malleiksi), joita käytetään pääasiassa samankaltaisten ongelmien ratkaisemiseen. Tämä mekanismi mahdollistaa luokan nimen välittämisen argumenttina geneeriselle tyypille ja vastaava objekti generoidaan. Voi olla parempi ajatella geneerisiä (mukaan lukien luokat, rajapinnat, metodit, delegaatit jne.) malleina, joissa varianttiosa korvataan argumenttina välitettävällä luokan nimellä, mikä johtaa uuteen tyyppimääritelmään. Geneerinen on suhteellisen laaja aihe, enkä aio analysoida sitä yksityiskohtaisesti tässä, ja kiinnostuneet voivat tutustua asiaankuuluvaan tietoon. Miten luon geneerisen kokoelman? List-generic-luokkaa System.Collections.Generic -nimiavaruuden <T>alla käytetään kokoelmien luomiseen, ja syntaksi on seuraava: [mw_shl_code=csharp, totta] List<T> OfT = uusi List<T>(); [/mw_shl_code] "T" on käytettävä tyyppi, joka voi olla yksinkertaisia tyyppejä, kuten merkkijono, int tai käyttäjän määrittelemät tyypit. Katsotaanpa tarkkaa esimerkkiä.
Henkilöluokka määritellään seuraavasti: [mw_shl_code=csharp,true]luokan henkilö
{ yksityinen jousi_name; Nimi yksityinen int _age; Ikä
Luo Henkilö-objekti julkinen henkilö (merkkijonon nimi, älykkyys ikä) { this._name= Nimi; this._age = Ikä; }
Nimi julkinen merkkijono Nimi { get { return _name; } }
Ikä public int Age { get { return _age; } }
}
//创建Person对象 Henkilö p1 = uusi henkilö ("Zhang San", 30); Henkilö p2 = uusi henkilö ("Li Si", 20); Henkilö p3 = uusi henkilö ("Wang Wu", 50);
//创建类型为Person的对象集合 <Person> Lista henkilöt = uusi Lista<Person>();
//将Person对象放入集合 henkilöitä. Add(p1); henkilöitä. Add(p2); henkilöitä. Add(p3);
//输出第2个人的姓名 Console.Write(henkilöt[1]. Nimi); [/mw_shl_code] Kuten näet, geneeriset kokoelmat yksinkertaistavat huomattavasti kokoelmien toteutuskoodia, jonka avulla voit helposti luoda tiettyjä kokoelmia. Lisäksi geneeriset kokoelmat tarjoavat tehokkaampia toimintoja, katsotaanpa niiden lajittelua ja hakua. Yleiskokoelmien lajittelu Lajittelu perustuu vertailuun, ja lajittelua varten sinun täytyy ensin vertailla. Esimerkiksi, jos on kaksi lukua 1 ja 2, niiden lajittelua varten meidän täytyy ensin verrata näitä kahta lukua ja lajitella ne vertailutulosten mukaan. Jos haluat verrata esineitä, tilanne on hieman monimutkaisempi; esimerkiksi jos vertaat henkilön esineitä, voit verrata nimen tai iän perusteella, mikä vaatii vertailusääntöjen määrittämistä. Oliolla voi olla useita vertailusääntöjä, mutta vain yksi oletussääntö, joka sijoitetaan luokkaan, joka määrittelee objektin. Oletusvertailusäännöt määritellään CompareTo-menetelmässä, joka kuuluu IComparable-yleiseen <T>rajapintaan. Katso alla oleva koodi: [mw_shl_code=csharp,true]luokka Henkilö :IComparable<Person>
{ Vertaa iän mukaan public int CompareTo(Henkilö p) { Palauta tämä. Ikä - p.Ikä; } }[/mw_shl_code] CompareTo-metodin parametrit ovat toinen samantyyppinen olio, johon verrataan, palautusarvo on int-tyyppi, jos palautusarvo on suurempi kuin 0, se tarkoittaa, että ensimmäinen objekti on suurempi kuin toinen objekti, jos palautusarvo on pienempi kuin 0, se tarkoittaa, että ensimmäinen objekti on pienempi kuin toinen objekti, ja jos se palauttaa 0, molemmat objektit ovat yhtä suuret. Kun olet määritellyt oletusvertailusäännöt, voit lajitella kokoelman Lajittelumenetelmällä ilman parametreja seuraavasti: [mw_shl_code=csharp,true]// Lajittele kokoelma oletussääntöjen mukaan henkilöitä. Sort();
//输出所有人姓名 foreach (henkilö p henkilöissä)
{ Console.WriteLine(p.Name); Tulostusjärjestys on "Li Si", "Zhang San" ja "Wang Wu" }[/mw_shl_code] Käytännössä kokoelma on usein tarpeen lajitella erilaisten sääntöjen mukaan, mikä edellyttää muiden vertailusääntöjen määrittelyä, jotka voidaan määritellä Vertailu-menetelmässä, joka kuuluu IComparerin <T>yleiseen rajapintaan, katso seuraava koodi: [mw_shl_code=csharp,true]class NimiVertailija : IComparer<Person>
{ Tallennussekvensseri-instanssi-instanssien julkinen staattinen NameComparer Default = uusi NameComparer();
Vertaa nimen mukaan julkinen int Vertaa (henkilö s1, henkilö s. 2) { return System.Collections.Comparer.Default.Compare(p1. Nimi, s. 2. Nimi); } }[/mw_shl_code] Vertailumenetelmän parametrit ovat kaksi samantyyppistä objektia, joita verrataan, palautusarvo on tyyppiä int, ja palautusarvojen käsittelysäännöt ovat samat kuin CompareTo-menetelmässä. Comparer.Default palauttaa sisäänrakennetun Comparer-objektin kahden samantyyppisen objektin vertailuun. Näin lajitellaan kokoelma tällä uudella vertailijalla: [mw_shl_code=csharp,true]//Lajittele kokoelma nimen mukaan henkilöitä. sort(NameComparer.Default);
//输出所有人姓名 foreach (henkilö p henkilöissä)
{ Console.WriteLine(p.Name); Tulostusjärjestys on "Li Si", "Wang Wu" ja "Zhang San" }[/mw_shl_code] Voit myös lajitella kokoelman delegoimalla ensin metodin, jonka delegaatti voi kutsua vertailusääntöjen tallentamiseen, ja voit käyttää staattista metodia. Katso alla oleva koodi: [mw_shl_code=csharp,true]luokan HenkilöVertailu
{ Vertaa nimen mukaan julkinen staattinen älykkyys Nimi (henkilö p1, henkilö s2) { return System.Collections.Comparer.Default.Compare(p1. Nimi, s. 2. Nimi); } }[/mw_shl_code] Metodin parametrit ovat kaksi samantyyppistä objektia, joita verrataan: palautusarvo on tyyppiä int, ja palautusarvon käsittelysääntö on sama kuin CompareTo-metodissa.Sitten lajittele kokoelma sisäänrakennetun yleisen delegaattijärjestelmän kautta. Vertailu<T>: [mw_shl_code=csharp, totta] System.Comparison<Person> NameComparison = uusi System.Comparison<Person>(PersonComparison.Name); henkilöitä. Sort(NimiVertailu);
//输出所有人姓名 foreach (henkilö p henkilöissä)
{ Console.WriteLine(p.Name); Tulostusjärjestys on "Li Si", "Wang Wu" ja "Zhang San" }[/mw_shl_code] On havaittavissa, että kaksi viimeksi mainittua menetelmää voivat lajitella kokoelman määriteltyjen sääntöjen mukaan, mutta tekijä suosii delegointimenetelmää ja voi harkita erilaisten vertailusääntöjen lisäämistä luokkaan ja niiden joustavaa kutsumista. Hae geneerisiä kokoelmia Haku tarkoittaa kokoelman tiettyjen ehtojen täyttävien kohteiden löytämistä, ja useita hakuehtoja voidaan määritellä ja kutsua tarpeen mukaan. Määritellään ensin hakukriteerit seuraavasti: [mw_shl_code=csharp,true]luokka Henkilöpredikaatti
{ Etsi keski-ikäisiä ihmisiä (yli 40) julkinen staattinen bool Keski-ikä (henkilö p) { jos (s. Ikä >= 40) return true; else palauta väärin; } }[/mw_shl_code] Yllä olevat hakukriteerit sijoitetaan staattiseen menetelmään, jossa on Boolen palautustyyppi, ja kokoelman kohteet, jotka täyttävät tietyt ehdot, palauttavat tosi tai muuten epätosi.Sitten hae kokoelmasta sisäänrakennetun yleisen delegaatin System.Predicate <T>kautta: [mw_shl_code=csharp, totta] System.Predikaatti<Person> MidAgePredicate = uusi System.Predicate <Person>(HenkilöPredicate.MidAge); Lista<Person> MidAgePersons = henkilöt. FindAll (Keski-ikäinen Predikaatti);
//输出所有的中年人姓名 foreach (henkilö p keski-ikäisten henkilöiden joukossa)
{ Console.WriteLine(p.Name); Lähtö "Wang Wu" }[/mw_shl_code] Yleiskokoelmien laajentaminen Entä jos haluat saada kaikkien setin henkilöiden nimet, erotettuna pilkulla? Koska yksittäisen luokan tarjoama toiminnallisuus on rajallinen, on luonnollista <T>ajatella List-luokan laajentamista, joka on myös luokka ja siksi sitä voidaan laajentaa periytymällä. Katso alla oleva koodi: [mw_shl_code=csharp,true]// Määrittele Person-kokoelmaluokka luokka Henkilöt: Luettelo<Person>
{ Hanki kaikkien kokoelman jäsenten nimet julkinen merkkijono GetAllNames() { jos (tämä. Lukumäärä == 0) return "";
merkkijono val = ""; foreach (henkilö p tässä) { val += p.Name + ","; }
Palauta Val. Alistring(0, val. Pituus - 1); }
}
//创建并填充Persons集合 Persons PersonCol = uudet Persons(); PersonCol.Add(p1); PersonCol.Add(p2); PersonCol.Add(s. 3);
//输出所有人姓名 Console.Write(PersonCol.GetAllNames()); Tulostus "Zhang San, Li Si, Wang Wu"[/mw_shl_code] Yhteenveto: Tämä artikkeli keskittyy geneeristen käyttöön C# 2.0:ssa kokoelmien toteuttamisessa sekä kokoelmatoiminnon laajentamisessa, ja geneeristen kokoelmien asianmukainen käyttö voi vähentää paljon päällekkäisyyttä ja parantaa kehityksen tehokkuutta merkittävästi. Itse asiassa sarjat ovat vain tyypillinen geneeristen sovellus, ja jos haluat tietää lisää geneerisistä, voit tutustua muihin asiaankuuluviin materiaaleihin. Toivottavasti tästä artikkelista oli sinulle hyötyä :-)
|