A InfoWiki wikiből
WikiSysop (vita | szerkesztései)
(Új oldal, tartalma: „<cim cim3="Indexelők" cim2="Objektum-orientált programozás" cim1="Magasszintű Programozási Nyelvek II." prev="mp3/ea13" next="mp3/ea15" back="mp3/Nyitolap...”)
Újabb szerkesztés →
Aktuális változat
Tartalomjegyzék |
Indexelők
A property úgy viselkedik, mintha fizikailag létező mező lenne. Van védelmi szintje (jellemzően 'public'), van típusa, és Kidolgozásától függően támogatja az adott típusú érték olvasásának (get) és írásának (set) műveletét.
Amennyiben a property-ből adatot olvasunk, úgy aktiválódik annak 'get' része, és kiolvasásra kerül (return) egy megfelelő típusú érték. Amennyiben a property-be értéket kívánunk írni, úgy aktiválódik a 'set' része, és az értéket ellenőrzi, majd feldolgozza (leggyakrabban tárolja).
A fenti műveletek végrehajtása a háttérben gyakorlatilag függvényhívásokat jelentenek, melyek aktiválását a property írás vagy olvasás művelete váltja ki.
Az indexelő, mint speciális property
Lehetőség van C#-ban egy speciális nevű property létrehozására, melynek a neve 'this'. Ezt a property-t indexelő-nek nevezzük. Nemcsak nevében speciális, hanem abban is, hogy ezen property-nek kivételesen paramétere is lehet:
class Sajat { public Object this[int index] { get { // kód kerül ide } set { // kód kerül ide } } }
Mint látszik, a 'this' property paraméterének a fenti példában a neve 'index', típusa 'int'. Az is látszik, hogy nem a szokásos gömbölyű zárójelpárban kell feltüntetni a property paraméterét, hanem szögletes zárójelpárban!
Az indexelő property aktiválása is speciális módon történik:
Sajat s = new Sajat(); Object p = s[3]; s[2] = null;
Az 'p=s[3]' során aktiválódik a 'this' nevű property, és a paraméter 'index=3' értéket fog felvenni. Mivel ekkor a 'this' nevű property olvasására van szükség, a 'get' rész indul el. A 'get' kódjában lehetőség van az 'index' paraméter értékének kiolvasására, majd segítségével elő lehet állítani a megfelelő értéket, és visszaadni azt egy 'return' segítségével.
A 's[2]=null' során a 'this' property 'set' része aktiválódik, az 'index=2' lesz, az elhelyezendő értéket pedig szokásos módon a 'value'-ban fogjuk megtalálni.
A fenti példa a speciális property, a 'this' indexelő használatát mutatta be. Mint láthatjuk, roppant speciális módon aktiválhatjuk ezt a property-t, a példányunkat mint egy vektort, tömböt kell használnunk, és ennek során tudjuk a 'get' vagy a 'set' részt indítani. Éppen ezért hívják ezt indexelő property-nek.
Ilyen indexelőt készítünk általában azon objektum-osztályainkhoz, amelyekben tárolt értékekre ilyen kényelmes szintaktikával kívánunk hivatkozni. A BCL is számtalan ilyet tartalmaz, mint pl. a 'string', 'ArrayList', 'Array' stb. osztályok esetén:
class String { public char this[int index] { get { return ('index'. betűje a szövegnek); } } }
A 'String' osztály esetén az indexelő egy karaktert ad vissza, a szóban forgó string n. betűjét. Ezen indexelőnek csak a 'get' része van kidolgozva, vagyis nem tudjuk átírni az n. betűértékét:
String s = "Helló"; char c = s[4]; // 'ó' betű s[2] = 'f'; // ez nem működik, nincs set !!!
Az indexelő paraméterezhetősége (1)
Minden indexelőnek kötelező paramétert adni, de a paraméterek típusára, számára nincs megszorítás. Ha az indexelőnknek mondjuk két int paramétere van, akkor az objektum-példány úgy viselkedik, mint egy mátrix:
class SajatMatrix { private int sorokSzama private int oszlopokSzama private int[,] tarolas; public SajatMatrix(int sorokSzama, int oszlopokSzama) { if (sorokSzama<=0 || oszlopokSzama<=0) throw new Exception("Ilyen matrix nincs is!"); this.sorokSzama = sorokSzama; this.oszlopokSzama = oszlopokSzama; tarolas = new int[sorokSzama, oszlopokSzama]; } public this[int i, int j] { get { if (0<= i && i<sorokSzama && 0<=j && j<oszlopokSzama) return tarolas[i,j]; else throw new IndexOutOfRangeException("Hibas indexeles!"); } set { if (0<= i && i<sorokSzama && 0<=j && j<oszlopokSzama) tarolas[i,j]=value; else throw new IndexOutOfRangeException("Hibas indexeles!"); } } } // ............. SajatMatrix m = new SajatMatrix(10,30); m[3,2] = 12; int x = m[4,1];
Az indexelő paraméterezhetősége (2)
A 'System.Collections.SortedList' osztály egy név-érték párosokat tartalmazó asszociatív vektor szerepét képes ellátni. A példány létrehozása után elemeket adhatunk hozzá, majd lekérdezhetjük valamely elem értékét annak azonosítója segítségével:
SortedList mySL = new SortedList(); mySL.Add("Nev", "Kiss Antal"); mySL.Add("Eletkor", 12); ... int eletkor = (int)mySL["Eletkor"]
Hogyan nézhet ki ez az osztály hogy ilyen intelligensen működik? Mind a kulcs mind az érték általános 'Object' típusú elem lehet, bár a fenti példában a kulcsok (azonosítók) mindegyik string volt:
class SortedList { public void Add(Object azonosito, Object ertek) { ... } public Object this[Object azonosito] { get { // az 'azonosito' kikeresése a listában // a hozzá tartozó érték visszaadása // ha nem található, akkor 'null' visszaadása } set { // az 'azonosito' kikeresése a listában // ha az létezik, akkor értékének cserélése 'value'-ra // különben új elem hozzáadása a név-érték párosokhoz } } }
A fenti példában látható, hogy az indexelő paramétere nem minden esetben 'int', sőt, általános esetben bármilyen típusú, akár valamely korábban deklarált saját objektum-osztályunk típusa is lehet.