1. Introduktion

Vi vet alla att Array inte är annat än sekvensiella minnesplatser där det lagrar data. Låt oss säga storleken på det fortsatta minnesplatsen är 80 kB och storleken på en dataenhet är 2 kB. Uttalandet innebär att vi har en matris med 40 data i sekvensiella minnesplatser. Bilden nedan förklarar detta:

Blocks of Memory |

Tänk till exempel arrayen nedan:

 Institutionen dpt = ny avdelning [40]; 

Om vi ​​antar att storleken som krävs för att lagra varje avdelning är 2 kB, har vi 40 block med storlek 2 kb tilldelas för att rymma 40 avdelningsobjekt. Observera också att 40 objekt tilldelas i sekvensordning. Så hur får vi objektet vid det tredje minnesblocket? Vi använder uttalandet nedan:

 Dpt [2]; 

Vad representerar [2] här? Det står att ta objektet från det tredje minnesblocket. Så här hänvisas varje minnesblock av den indexerade platsen. Så notationen [] är det som kallas Indexer .

I den här artikeln kommer vi att skapa en samlingsklass och sedan se hur vi kan implementera en enkel positionsbaserad indexerare och värdebaserad indexerare .

2. Produktklass

Vi tar hänsyn till nedan angivna enkla klass som representerar produkten för en butik. Den har två privata datamedlemmar, en konstruktör och en offentlig metod för att ställa in eller hämta datamedlemmarna.

 // 001: Produktklass. public class Product {privat int ProductId; privat sträng Produktnamn; offentlig produkt (int-id, strängnamn) {ProductId = id; Produktnamn = Namn; } public string GetProdName () {returnera ProductName; }} 

3. SuperMarket Class

Eftersom varje Supermarknad har en samling produkter kommer denna klass att ha en samling av ett produktobjekt. Medlemmarna i denna klass visas nedan:

 // 002: SuperMarket har produktsamling. // Det implementerar indexerare. public class SuperMarketX {// 002_1: Förklaring privat int pos; privat sträng butiksnamn; privat produkt [] Produkter; // 0-Position baserat index. 1-värdebaserat index. public int numeric_index_mode; 

Variabeln "Pos" är att iterera genom produktsamlingen. OK, du kanske får idén nu. Klassen SuperMarket är en användardefinierad (definierad av oss nu) produktkollektion.

Konstruktören för denna klass kommer att ta en rad produkter som en parameter och tilldelar den till den privata medlemmen i Products-instansen. Observera att för denna artikel tilldelar vi ett fast utrymme på 1000 platser och varje utrymme har initialt nollreferens. Vi kommer att ersätta nollreferensen med den överförda i arrayen av objekt. Nedan är koden för konstruktören:

 // 002_2: Constructor public SuperMarketX (string shopname, params Product [] products) {//002_2.1: Tilldela det utrymme som krävs detta. Produkter = ny produkt [1000]; pos = 0; //002_2.2: Ställ först noll till alla element för (int i = 0; i <1000; i ++) Produkter [i] = null; //002_2.3: Tilldela Array genom att ta referenser // från inkommande matris. Hänvisningen kommer att ersätta // det föregående nulltilldelningsförfarandet (Produktprd i produkter) {Produkter [pos] = prd; pos ++; } //002_2.4: Ställ in butikens namn och indexera detta.shopname = butiksnamn; numeric_index_mode = 0; } 

Vi åsidosätter metoden ToString () för att få hela produkten i ett kommaseparerat format. Metodimplementeringen visas nedan:

 // 004: åsidosätta ToString till // visa alla produktnamn som // Kommaseparerad lista offentlig åsidosättningssträng ToString () {string returnval = ""; förhand (produkt p i produkter) {if (p! = null) returnval = returnval + ", " + p.GetProdName (); } // Klipp av den ledande ", " och returen return return.Substring (1, returnval.Length-1); } 

4. Positionsbaserad indexerare

Indexet kommer att implementera precis som operatörens överbelastningsfunktioner. Följ nedan syntax för att implementera notationen '[]':

Syntax för C # Indexer |

Implementeringsskelettet på Simple Indexer visas nedan:

Position baserad Indexer |

I bilden ovan kan vi se att få en del av indexeraren kallas när vi vill läsa från samlingen med "Index Of" -operatören. På samma sätt blir det avsnitt att ringa när vi vill skriva till samlingen.

I vårt fall kommer vi att implementera indexet för stormarknaden. Så med hjälp av Positivt index kommer vi att hämta en produkt. Det sätt som implementerat index ger en NULL-referens till den som ringer när indexet är utanför intervall Säg under 0 eller över 1000. Observera att den maximala produkt som stöds av stormarknaden är 1000. Nedan är funktionens implementering:

 // 003: Användning av indexerare. Positional Indexer public Produkt detta [int index] {get {// 003_1: Hämta värde baserat på // positionsindex if (index> = Products.Length || index = Products.Length) {return; } Produkter [index] = värde; }} 

Klientkoden som använder indexeraren anges nedan.

 // Client 001: Först Låt oss skapa en matris // för att hålla 6 produkter. Produkt [] theProdArray = ny produkt [6]; // Client 002: Skapa 6 enskilda produkter och // lagra den i matrisen theProdArray [0] = ny produkt (1001, "Beer"); theProdArray [1] = ny produkt (1002, "Soda"); theProdArray [2] = ny produkt (1003, "Te"); theProdArray [3] = ny produkt (1004, "kaffe"); theProdArray [4] = ny produkt (1005, "Apple"); theProdArray [5] = ny produkt (1006, "druvor"); // Client 003: Super Market som innehar sex // produktsamling SuperMarketX market = new SuperMarketX ("Z Stores", theProdArray); Console.WriteLine ("Produkt tillgänglig i Super Market:" + marknad); // Client 004: Använd Simple // Indexer för att tilldela värdemarknaden [15] = ny produkt (1015, "Orange"); Console.WriteLine ("Produkt tillgänglig i Super Market:" + marknad); // Client 005: Använd Simple Indexer för att // hämta värdet Product prod = market [5]; Console.WriteLine ("Hämtad produkt är:" + prod.GetProdName ()); 

Kodförklaring

  1. Klient 001: Skapar arrayen av 6 produkter.
  2. Klient 002: Populerar produktfältet. I den verkliga världen kommer Array att byggas från databasen.
  3. Klient 003: Supermarket skapas med 6 nya produkter. Observera, i vårt exempel är stormarknadens kapacitet 1000.
  4. Klient 004: använder indexeraren för att lägga till en ny produkt i produktsamlingen. marknad [15] = ny produkt (1015, "Orange"); Ringer indexören med index = 15. ny produkt (1015, "Orange"); kommer att hänvisas till den inställda delen av vår Indexer med hjälp av nyckelordet.
  5. Klient 005: Produktprodukt = marknad [5]; Stormarknadsobjekt åtkomst till Indexer [5]. Vi kommer att flytta för att få en del av Indexer och indexeraren returnerar Produkten vid positionskompensering 5. Den returnerade objektreferensen tilldelas prod.

5. Värdebaserad indexerare

Den föregående indexeraren lokaliserar minnesblocket baserat på indexet genom att beräkna förskjutningen eftersom den vet storleken på minnesblocket. Nu kommer vi att implementera värdebaserat index som får produkten baserad på ProductId-värdet. Vi kommer att gå igenom förändringarna i klasserna.

1) Produktklassen har ändrats till att ha en metod som anger produktnamn och en get-metod för ProductId. Vi har också en åsidosatt metod för ToString bara för att skriva ut produktnamn. Nedan visas ändringarna:

 public override string ToString () {returnera ProductName; } public int GetProductId () {returnera ProductId; } public void SetProductName (string newName) {ProductName = newName; } 

2) I SuperMarket-klassen förklarar vi en variabel som heter numeric_index_mode. Vi använder denna variabel för att bestämma om indexeraren kallas position-baserad eller i värde-baserad.

 // 0-Position baserat index. 1-värdebaserat index. public int numeric_index_mode; 

Inuti konstruktören initierar vi indexeringsläge till 0. Det innebär att SuperMarket-klassen som standard behandlar Indexer som Positiv indexerare och hämtar produkten baserat på den beräknade positionsförskjutningen.

 numeric_index_mode = 0; 

3) Vi implementerar en offentlig funktion för att hämta Positionsindex för den godkända produkt-ID. Observera att produkt-ID är unikt för detta värdebaserade index. Funktionen upprepas genom produkterna i stormarknaden och återgår när en matchning för produkt-ID hittas. Det kommer att returnera 1 när match inte inträffat. Nedan visas den nya funktionen som implementeras för att stödja det värdebaserade indexet:

 // 005: Stödfunktion för värdebaserad Index public int GetProduct (int Productid) {för (int i = 0; i <Products.Length; i ++) {Product p = Products [i]; if (p! = null) {int prodid = p.GetProductId (); if (prodid == Productid) return i; }} tillbaka -1; } 

4) Först, i indexdelen för get, ska du linda in den befintliga koden med en if-konstruktion. Det är; när läget = 0, gå med positionsindex. Det gäller även för Set-delen av Indexer. Nedan visas förändringen:

 public Product this [int index] {get {// 003_1: Hämta produkt baserat på // positionsindex if (numeric_index_mode == 0) {if (index> = Products.Length || index = Products.Length) {return; } Produkter [index] = värde; }}} 

5) Om vi ​​är i värde-läge, får du i positionen Hämta först indexeringspositionen för ett produkt-id. När vi väl har ett positionsindex är vi redo att ringa ett rekursivt samtal till samma indexeringsrutin. Se till att ställa in indexeringsläget till 0 eftersom vi måste komma åt indexeraren för att få produkten baserad på den indexerade positionen. När vi har fått produkten, återställ indexläget tillbaka till 1; att återställa indexeringsläget till värde baserat på klientkoden förväntar sig det. Nedan är koden för "Get" -delen:

 // 003_2: Hämta produkt baserat på den unika produkt-id if (numeric_index_mode == 1) {int idx = GetProduct (index); om (idx == -1) returnera null; annars {// Nyckelmeddelande för att undvika rekursion numeric_index_mode = 0; // Rekursivt samtal till Indexer Product ret_Product = detta [idx]; // Återställ den till användarinställningar numeric_index_mode = 1; return ret_Product; } 

Observera att vi kan ändra GetProduct-funktionen för att returnera en produkt och göra denna implementering enkel.

6) Den inställda delen av indexeraren ändrades också på samma sätt. Jag hoppas att ytterligare förklaring inte krävs:

 // 003_3: Ställ in värdet baserat på den ID som passerat. If (numeric_index_mode == 1) {int idx = GetProduct (index); om (idx == -1) tillbaka; annars {// Nyckelmeddelande för att undvika rekursion numeric_index_mode = 0; Produkter [idx] = värde; // Återställ den till användarinställningar numeric_index_mode = 1; }} 

Använda värdebaserad indexerare

Koden nedan förklarar hur vi växlar från positionsbaserad indexerare till värdebaserad indexerare, använder värdebaserad indexerare och går tillbaka till standardindexläget. Läs inline kommentarerna så är det lätt att följa.

 // =====> Värde baserat index <======= // Nu kommer vi att verka på det värdebaserade indexmarknaden.numeric_index_mode = 1; // Client 006: Visningsnamn på produkten // vars produkt-id är 1005 Console.WriteLine ("Produktens namn" + "representerat av Id 1005 är: {0}", marknad [1005]); // Client 007: Målet är Ersätt produkten // Soda med Iced Soda och upprätthålla samma produkt-id. // Id of Soda är 1002. if (market [1002]! = Null) {market [1002] .SetProductName ("Iced Soda"); Console.WriteLine ("Produkten finns i" + "Supermarknad:" + marknad); } // Klient 008: Ta bort te och lägg till franskt kaffe. // Observera att objektet på den indexerade platsen // kommer att ändras. // Obs: Här kontrollerar du att noll inte krävs. // Kind of Modify on fail Lägg till marknad [1003] = ny produkt (1007, "French Coffee"); Console.WriteLine ("Produkten finns i" + "Supermarknad:" + marknad); // Återställ tillbaka till Standard Positional Index market.numeric_index_mode = 0; //Punkt 

6. Avslutande anteckningar

1) Du kan också implementera strängvärdebaserad indexerare. Skelettet är:

 public Product this [string ProductName] {Set {} Get {}} 

Komplett källkod

Indexer.cs

 använder System; namespace _005_Indexers {// 001: Product Class. public class Product {privat int ProductId; privat sträng Produktnamn; offentlig produkt (int-id, strängnamn) {ProductId = id; Produktnamn = Namn; } public string GetProdName () {returnera ProductName; } offentlig åsidosättande sträng ToString () {returnera produktnamn; } public int GetProductId () {returnera ProductId; } public void SetProductName (string newName) {ProductName = newName; }} // 002: SuperMarket har produktsamling. Det implementerar indexerare. public class SuperMarketX {// 002_1: Förklaring privat int pos; privat sträng butiksnamn; privat produkt [] Produkter; // 0-Position baserat index. 1-värdebaserat index. public int numeric_index_mode; // 002_2: Constructor public SuperMarketX (string shopname, params Product [] products) {//002_2.1: Tilldela det utrymme som krävs detta. Produkter = ny produkt [1000]; pos = 0; //002_2.2: ställer först noll till alla element för (int i = 0; i = Products.Length || index = Products.Length) {return; } Produkter [index] = värde; } // 003_3: Ställ in värdet baserat på den ID som passerat. If (numeric_index_mode == 1) {int idx = GetProduct (index); om (idx == -1) tillbaka; annars {// Nyckelmeddelande för att undvika rekursion numeric_index_mode = 0; Produkter [idx] = värde; // Återställ den till användarinställningar numeric_index_mode = 1; }}}} // 004: åsidosätta ToString för att visa alla produktnamn som kommaseparerad lista offentlig åsidosättningssträng ToString () {string returnval = ""; förhand (produkt p i produkter) {if (p! = null) returnval = returnval + ", " + p.GetProdName (); } // Klipp av den ledande ", " och returen return return.Substring (1, returnval.Length-1); } // 005: Stödfunktion för värdebaserad Index public int GetProduct (int Productid) {för (int i = 0; i  Värde baserat index <======= // Nu kommer vi att verka på det värdebaserade indexmarknaden. Nummer_index_mode = 1; // Client 006: Visningsnamn på produkten // vars produkt-id är 1005 Console.WriteLine ("Produktens namn" + "representerat av Id 1005 är: {0}", marknad [1005]); // Client 007: Målet är Ersätt produkten // Soda med Iced Soda och upprätthålla samma produkt-id. // Id of Soda är 1002. if (market [1002]! = Null) {market [1002] .SetProductName ("Iced Soda"); Console.WriteLine ("Produkten finns i" + "Supermarknad:" + marknad); } // Klient 008: Ta bort te och lägg till franskt kaffe. // Observera att objektet på den indexerade platsen // kommer att ändras. // Obs: Här kontrollerar du att noll inte krävs. // Kind of Modify on fail Lägg till marknad [1003] = ny produkt (1007, "French Coffee"); Console.WriteLine ("Produkten finns i" + "Supermarknad:" + marknad); // Återställ tillbaka till Standard Positional Index market.numeric_index_mode = 0; // Dot}}} 

Kodens utgång

Utgången för att utföra exemplet ovan ges nedan:

Position och värdebaserad indexerutgång |