Samlingar är ett viktigt begrepp inom OOP, och fullt stöd för samlingar i C# är ett av de bästa inom språket.
Varför använda generiska set? Före C# 2.0 kunde samlingar implementeras på två huvudsakliga sätt: a. Använd ArrayList Att lägga objekt direkt i ArrayList är intuitivt, men eftersom objekten i samlingen är av typen Objekt måste du göra en tråkig typkonvertering varje gång du använder den. b. Använd anpassade samlingsklasser En vanlig praxis är att ärva en anpassad klass från CollectionBase-abstraktklassen och implementera en stark typsamling genom att kapsla in IList-objektet. Denna metod kräver att man skriver en motsvarande anpassad klass för varje samlingstyp, vilket är mycket arbete. Framväxten av generiska samlingar löser ovanstående problem väl, och endast en kodrad kan användas för att skapa en mängd av en specificerad typ. Vad är generiskt? Generiska är nya element i C# 2.0 (kallade mallar i C++) som främst används för att lösa en serie liknande problem. Denna mekanism tillåter att klassnamnet kan skickas som ett argument till den generiska typen och motsvarande objekt genereras. Det kan vara bättre att tänka på generiska (inklusive klasser, gränssnitt, metoder, delegater etc.) som mallar, där variantdelen ersätts av klassnamnet som skickas som ett argument, vilket resulterar i en ny typdefinition. Generiskt är ett relativt stort ämne, och jag kommer inte att analysera det i detalj här, och de som är intresserade kan konsultera relevant information. Hur skapar jag en generisk samling? List-generiska klassen under System.Collections.Generic <T>namnrymden används för att skapa samlingar, och syntaxen är följande: [mw_shl_code=csharp, sant] List<T> ListOfT = ny List<T>(); [/mw_shl_code] "T" är typen som ska användas, vilket kan vara enkla typer, såsom sträng, int eller användardefinierade typer. Låt oss titta på ett specifikt exempel.
Person-klassen definieras enligt följande: [mw_shl_code=csharp, true]klass Person
{ privat sträng _name; Namn privat int _age; Ålder
Skapa ett Person-objekt offentlig person (strängnamn, ålder) { this._name= Namn; this._age = Ålder; }
Namn publikt strängnamn { get { return _name; } }
Ålder offentlig int Ålder { get { return _age; } }
}
//创建Person对象 Person p1 = ny person ("Zhang San", 30); Person p2 = ny person ("Li Si", 20); Person p3 = ny person ("Wang Wu", 50);
//创建类型为Person的对象集合 Listapersoner<Person> = ny Lista<Person>();
//将Person对象放入集合 personer. Add(p1); personer. Add(p2); personer. Add(s3);
//输出第2个人的姓名 Konsol.Skriv(personer[1]. Namn); [/mw_shl_code] Som du kan se förenklar generiska samlingar implementeringskoden för samlingar avsevärt, genom vilka du enkelt kan skapa samlingar av specificerade typer. Inte nog med det, generiska samlingar ger också kraftfullare funktioner, låt oss titta på sortering och sökning i dem. Sortering av generiska samlingar Sortering baseras på jämförelse, och för att sortera måste du först jämföra. Till exempel, om det finns två siffror, 1 och 2, måste vi för att sortera dem först jämföra dessa två nummer och sortera dem enligt jämförelseresultaten. Om du vill jämföra objekt är situationen lite mer komplicerad, till exempel om du jämför Personobjekt kan du jämföra efter namn eller ålder, vilket kräver att du bestämmer jämförelsereglerna. Ett objekt kan ha flera jämförelseregler, men endast en standardregel, som placeras i klassen som definierar objektet. Standardreglerna för jämförelse definieras i CompareTo-metoden, som tillhör IComparables <T>generiska gränssnitt. Se koden nedan: [mw_shl_code=csharp, true]klass Person: IComparable<Person>
{ Jämför efter ålder offentlig int CompareTo(Person p) { Lämna tillbaka det här. Ålder - p.Ålder; } }[/mw_shl_code] Parametrarna i CompareTo-metoden är ett annat objekt av samma typ att jämföra med, returvärdet är int-typ, om returvärdet är större än 0 betyder det att det första objektet är större än det andra objektet, om returvärdet är mindre än 0 betyder det att det första objektet är mindre än det andra objektet, och om det returnerar 0 är de två objekten lika. Efter att ha definierat standardjämförelsereglerna kan du sortera samlingen med sorteringsmetoden utan parametrar, enligt följande: [mw_shl_code=csharp, true]// Sortera samlingen enligt standardreglerna personer. Sort();
//输出所有人姓名 foreach (Person p i personer)
{ Console.WriteLine(p.Name); Utgångsordningen är "Li Si", "Zhang San" och "Wang Wu" }[/mw_shl_code] I praktiken är det ofta nödvändigt att sortera samlingen enligt olika regler, vilket kräver definition av andra jämförelseregler, vilka kan definieras i Compere-metoden, vilken tillhör IComparers <T>generiska gränssnitt, se följande kod: [mw_shl_code=csharp,true]-klass NamnJämförare : IComparer<Person>
{ Lagringssekvenserinstanser publik statisk NameComparer Default = ny NameComparer();
Jämför efter namn offentlig int Jämför (Person p1, Person p2) { return System.Collections.Comparer.Default.Compare(p1. Namn, s2. Namn); } }[/mw_shl_code] Parametrarna för Compare-metoden är två objekt av samma typ som ska jämföras, och returvärdet är av typen int, medan reglerna för bearbetning av returvärde är desamma som i CompareTo-metoden. Comparer.Default returnerar ett inbyggt Comparer-objekt för att jämföra två objekt av samma typ. Så här sorterar du samlingen med denna nydefinierade komparator: [mw_shl_code=csharp, true]//Sortera samlingen efter namn personer. Sortera(NameComparer.Default);
//输出所有人姓名 foreach (Person p i personer)
{ Console.WriteLine(p.Name); Utgångsordningen är "Li Si", "Wang Wu" och "Zhang San" }[/mw_shl_code] Du kan också sortera samlingen genom att delegera, först och främst definiera en metod som delegaten ska kalla för att lagra jämförelsereglerna, och du kan använda en statisk metod. Se koden nedan: [mw_shl_code=csharp,true]klass PersonJämförelse
{ Jämför efter namn offentlig statisk int Namn (Person p1, Person p2) { return System.Collections.Comparer.Default.Compare(p1. Namn, s2. Namn); } }[/mw_shl_code] Parametrarna för metoden är två objekt av samma typ som ska jämföras, returvärdet är av typen int, och regeln för bearbetning av returvärde är densamma som för CompareTo-metoden.Sortera sedan samlingen via det inbyggda generiska delegatsystemet. Jämförelse<T>: [mw_shl_code=csharp, sant] System.Jämförelse<Person> NamnJämförelse = nytt System.Jämförelse<Person>(PersonComparison.Name); personer. Sortera(Namnjämförelse);
//输出所有人姓名 foreach (Person p i personer)
{ Console.WriteLine(p.Name); Utgångsordningen är "Li Si", "Wang Wu" och "Zhang San" }[/mw_shl_code] Det kan ses att de två senare metoderna kan sortera samlingen enligt de specificerade reglerna, men författaren föredrar att använda delegeringsmetoden och kan överväga att lägga olika jämförelseregler i en klass och sedan anropa dem flexibelt. Sök efter generiska samlingar Sökning är för att hitta objekt som uppfyller specifika villkor från samlingen, och flera sökvillkor kan definieras och anropas vid behov. Definiera först sökkriterierna enligt följande: [mw_shl_code=csharp,true]klass PersonPredicate
{ Hitta medelålders personer (över 40) offentlig statisk bool MidAge (Person p) { om (p.Age >= 40) återvänd sant; annars returnera falsk; } }[/mw_shl_code] Ovanstående sökkriterier placeras i en statisk metod med en boolesk returtyp, och objekt i samlingen som uppfyller vissa villkor returnerar sant, annars falskt.Sök sedan i samlingen via det inbyggda generiska delegatsystemet. Predicate<T>: [mw_shl_code=csharp, sant] System.Predikat<Person> MidAgePredikat = nytt System.Predikat <Person>(PersonPredikat.MidAge); Lista<Person> MidAgePersons = personer. FindAll(MidAgePredicate);
//输出所有的中年人姓名 foreach (Person p i MidAgePersons)
{ Console.WriteLine(p.Name); Utgång "Wang Wu" }[/mw_shl_code] Utvidgning av generiska samlingar Vad händer om du vill få namnen på alla personer i setet, separerade med ett kommatecken? Eftersom funktionaliteten som en enskild klass kan erbjuda är begränsad är det naturligt att tänka <T>på att utöka List-klassen, som också är en klass och därför kan utökas genom arv. Se koden nedan: [mw_shl_code=csharp,true]// Definiera Persons-samlingsklassen klasspersoner : Lista<Person>
{ Få namnen på alla i samlingen publik sträng GetAllNames() { Om (detta. Antal == 0) återvända "";
sträng val = ""; foreach (Person p i detta) { val += p.Name + ","; }
Återvänd Val. Substring(0, val. Längd - 1); }
}
//创建并填充Persons集合 PersonPersonCol = nya personer(); PersonCol.Add (s1); PersonCol.Add (s2); PersonCol.Add (s3);
//输出所有人姓名 Console.Write(PersonCol.GetAllNames()); Utgång "Zhang San, Li Si, Wang Wu"[/mw_shl_code] Sammanfattning: Denna artikel fokuserar på användningen av generiska i C# 2.0 för att implementera samlingar, samt för att utöka samlingsfunktionen, och korrekt användning av generiska samlingar kan minska mycket dubbelarbete och avsevärt förbättra utvecklingseffektiviteten. Faktum är att mängder bara är en typisk tillämpning av generika, och om du vill veta mer om generika kan du konsultera andra relevanta material. Hoppas den här artikeln var till nytta för dig :-)
|