Zbirke so pomemben koncept v OOP, polna podpora zbirkam v C# pa je ena najboljših v jeziku.
Zakaj uporabljati generične komplete? Pred C# 2.0 so bile zbirke mogoče implementirati na dva glavna načina: a. Uporaba ArrayList Vstavljanje objektov neposredno v ArrayList je intuitivno, vendar ker so elementi v zbirki tipa Object, morate vsakič, ko ga uporabljate, izvajati dolgočasno pretvorbo tipov. b. Uporaba razredov po meri Pogosta praksa je, da se iz abstraktnega razreda CollectionBase podeduje prilagojen razred in implementira močno zbirko tipov z enkapsulacijo objekta IList. Ta metoda zahteva pisanje ustreznega prilagojenega razreda za vsak tip zbirke, kar je veliko dela. Pojav generičnih zbirk dobro reši zgoraj omenjene probleme, zato je mogoče uporabiti le eno vrstico kode za ustvarjanje množice določenega tipa. Kaj je generično? Generični elementi so novi elementi v C# 2.0 (imenovani predloge v C++), ki se večinoma uporabljajo za reševanje niza podobnih problemov. Ta mehanizem omogoča, da se ime razreda posreduje kot argument generičnemu tipu in se generira ustrezni objekt. Morda je bolje razmišljati o generičnih (vključno s razredi, vmesniki, metodami, delegati itd.) kot o predlogah, kjer je variantni del zamenjan z imenom razreda, ki se posreduje kot argument, kar vodi do nove definicije tipa. Splošna tema je razmeroma obsežna in je tukaj ne bom podrobno analiziral, tisti, ki jih zanima, pa lahko pogledajo ustrezne informacije. Kako ustvarim generično zbirko? Generični razred List pod imenskim prostorom System.Collections.Generic <T>se uporablja za ustvarjanje zbirk, sintaksa pa je naslednja: [mw_shl_code=csharp, resnično] <T> List ListOfT = novi List<T>(); [/mw_shl_code] "T" je tip, ki se uporablja, in so lahko preprosti tipi, kot so string, int ali uporabniško definirani tipi. Poglejmo konkreten primer.
Razred Person je definiran takole: [mw_shl_code=csharp,true]razredna oseba
{ zasebni strunski _name; Ime zasebni int _age; Starost
Ustvari objekt Person javna oseba (ime stringa, int starost) { this._name= Ime; this._age = Starost; }
Ime javna struna Ime { dobi { return _name; } }
Starost javno int Starost { dobi { return _age; } }
}
//创建Person对象 Oseba p1 = nova oseba ("Zhang San", 30); Oseba p2 = nova oseba ("Li Si", 20); Oseba p3 = nova oseba ("Wang Wu", 50);
//创建类型为Person的对象集合 <Person> Seznam oseb = nov Seznam<Person>();
//将Person对象放入集合 osebe. Add(p1); osebe. Add(p2); osebe. Add(p3);
//输出第2个人的姓名 Console.Write(osebe[1]. Ime); [/mw_shl_code] Kot vidite, generične zbirke močno poenostavijo implementacijsko kodo zbirk, s katero lahko enostavno ustvarite zbirke določenih tipov. Poleg tega generične zbirke nudijo tudi močnejše funkcije, poglejmo si razvrščanje in iskanje v njih. Razvrščanje generičnih zbirk Razvrščanje temelji na primerjavi, in za razvrščanje morate najprej primerjati. Na primer, če sta dve številki 1 in 2, ju moramo za razvrstitev najprej primerjati ti dve številki in ju razvrstiti glede na rezultate primerjave. Če želite primerjati predmete, je situacija nekoliko bolj zapletena; na primer, če primerjate objekte Osebe, lahko primerjate po imenu ali starosti, kar zahteva določitev pravil primerjave. Objekt ima lahko več primerjalnih pravil, vendar le eno privzeto pravilo, ki je postavljeno v razred, ki definira objekt. Privzeta primerjalna pravila so definirana v metodi CompareTo, ki spada v generični vmesnik IComparable<T>. Oglejte si spodnjo kodo: [mw_shl_code=csharp,true]razredna oseba :IComparable<Person>
{ Primerjajte po starosti public int CompareTo(Person p) { Vrni to. Starost - p. Starost; } }[/mw_shl_code] Parametri metode CompareTo so drug objekt iste vrste, s katerim se primerja, povratna vrednost je int tip, če je povratna vrednost večja od 0, pomeni, da je prvi objekt večji od drugega, če je povratna vrednost manjša od 0, pomeni, da je prvi objekt manjši od drugega, in če vrne 0, sta oba objekta enaka. Po določitvi privzetih pravil primerjave lahko zbirko razvrstite z metodo Sort brez parametrov, kot sledi: [mw_shl_code=csharp,true]// Razvrsti zbirko po privzetih pravilih osebe. sort();
//输出所有人姓名 foreach (oseba p v osebah)
{ Console.WriteLine(p.Name); Vrstni red izhoda je "Li Si", "Zhang San" in "Wang Wu" }[/mw_shl_code] V praksi je pogosto potrebno razvrstiti zbirko po različnih pravilih, kar zahteva definicijo drugih primerjalnih pravil, ki jih je mogoče definirati v metodi Compable, ki pripada <T>generičnemu vmesniku IComparer; prosimo, glejte naslednjo kodo: [mw_shl_code=csharp,true]razred Primerjalnik imen: IComparer<Person>
{ Instance sekvencerjev za shranjevanje javni statični NameComparer Privzeto = nov NameComparer();
Primerjajte po imenu javni int Primerjaj(Oseba p1, Oseba p2) { return System.Collections.Comparer.Default.Compare(p1. Ime, str. 2. Ime); } }[/mw_shl_code] Parametri metode Compare so dva objekta istega tipa, ki ju primerjajo, vrnjena vrednost je tipa int, pravila obdelave vrnjene vrednosti pa so enaka kot pri metodi CompareTo. Comparer.Default vrne vgrajen Comparer objekt za primerjavo dveh objektov iste vrste. Tukaj je, kako razvrstiti zbirko s tem novo definiranim primerjalnikom: [mw_shl_code=csharp,true]//Razvrsti zbirko po imenu osebe. Sort(NameComparer.Default);
//输出所有人姓名 foreach (oseba p v osebah)
{ Console.WriteLine(p.Name); Vrstni red izhoda je "Li Si", "Wang Wu" in "Zhang San" }[/mw_shl_code] Zbirko lahko tudi razvrstite z delegiranjem, najprej določite metodo, ki jo delegat kliče za shranjevanje primerjalnih pravil, in uporabite statično metodo. Oglejte si spodnjo kodo: [mw_shl_code=csharp,true]razred OsebaPrimerjava
{ Primerjajte po imenu javni statični int Ime (Oseba p1, Oseba p2) { return System.Collections.Comparer.Default.Compare(p1. Ime, str. 2. Ime); } }[/mw_shl_code] Parametri metode so dva objekta istega tipa, ki ju primerjajo, povratna vrednost je tipa int, pravilo obdelave vrnjene vrednosti pa je enako kot pri metodi CompareTo.Nato razvrstite zbirko preko vgrajenega generičnega sistema delegatov. Primerjava<T>: [mw_shl_code=csharp, resnično] <Person> System.Comparison NameComparison = novi System.Comparison<Person>(PersonComparison.Name); osebe. Sort(NameComparison);
//输出所有人姓名 foreach (oseba p v osebah)
{ Console.WriteLine(p.Name); Vrstni red izhoda je "Li Si", "Wang Wu" in "Zhang San" }[/mw_shl_code] Vidimo, da lahko zadnji dve metodi razvrstita zbirko po določenih pravilih, vendar avtor raje uporablja metodo delegiranja in lahko razmisli, da v razred postavita različna pravila primerjave ter jih nato fleksibilno pokliče. Iskanje generičnih zbirk Iskanje je namenjeno iskanju elementov, ki izpolnjujejo določene pogoje iz zbirke, pri čemer je mogoče definirati in klicati več iskalnih pogojev po potrebi. Najprej definirajte kriterije iskanja takole: [mw_shl_code=csharp,true]razredna oseba Preddikat
{ Poiščite ljudi srednjih let (nad 40 let) javni statični bool MidAge (Oseba p) { če (p.Starost >= 40) vrni true; else return false; } }[/mw_shl_code] Zgornja merila iskanja so postavljena v statični metodi z Booleovim tipom vrnitve, in elementi v zbirki, ki izpolnjujejo določene pogoje, vrnejo resnico, sicer napačno.Nato preiščite zbirko preko vgrajenega generičnega sistema delegatov. Predikat<T>: [mw_shl_code=csharp, resnično] System.Predicate<Person> MidAgePredicate = novi System.Predicate<Person>(PersonPredicate.MidAge); Seznam<Person> MidAgePersons = osebe. FindAll(MidAgePredicate);
//输出所有的中年人姓名 foreach (Oseba p v MidAgePersons)
{ Console.WriteLine(p.Name); Izhod "Wang Wu" }[/mw_shl_code] Razširitev generičnih zbirk Kaj pa, če želiš dobiti imena vseh ljudi v nizu, ločena z vejico? Glede na to, da je funkcionalnost, ki jo lahko zagotovi en razred, omejena, je naravno razmišljati <T>o razširitvi razreda List, ki je prav tako razred in ga je zato mogoče razširiti z dedovanjem. Oglejte si spodnjo kodo: [mw_shl_code=csharp,true]// Definiraj razred zbirke Persons Razred Osebe: Seznam<Person>
{ Pridobite imena vseh v zbirki javni niz GetAllNames() { če (to. Število == 0) vrni """;
niz val = ""; foreach (Oseba p v tem) { val += p.Name + ","; }
Vrni Val. Podniz(0, val. Dolžina - 1); }
}
//创建并填充Persons集合 OsebeCol = nove osebe(); OsebaCol.Add(p1); OsebaCol.Add(p2); OsebaCol.Add(str. 3);
//输出所有人姓名 Console.Write(PersonCol.GetAllNames()); Izhod "Zhang San, Li Si, Wang Wu"[/mw_shl_code] Povzetek: Ta članek se osredotoča na uporabo generičnih vsebin v C# 2.0 za implementacijo zbirk ter za razširitev funkcije zbiranja, pravilna uporaba generičnih zbirk pa lahko zmanjša veliko podvajanja dela in bistveno izboljša učinkovitost razvoja. Pravzaprav so kompleti le tipična uporaba generikov, in če želite izvedeti več o generiki, lahko pogledate tudi druge relevantne materiale. Upam, da vam je bil ta članek v pomoč :-)
|