Indeksatory

darek963

Zrozumienie artykułu wymaga znajomości: tablic, Klasy, Właściwości, akcesorów.

Indeksator

Dobra praktyka programowania obiektowego mówi, że zmienne deklarowane na poziomie klasy powinny być prywatne. Jeżeli chcemy odwoływać się do nich z kodu umieszczonego poza klasą powinniśmy zaimplementować publiczne właściwości, które będą na nich operować. A co zrobić jeśli mamy tablicę zadeklarowaną na poziomie klasy? W języku C# z pomocą przychodzą nam indeksatory (ang. indexers). Zaimplementowanie indeksatora pozwala nam odwoływać się do tablicy w klasie po samej nazwie obiektu i indeksie. Istnieje tutaj jednak pewne ograniczenie, klasa zawierająca indeksator może mieć zadeklarowaną tylko jedną [[C sharp/tablice|tablicę]]. Podobnie jak [[C sharp/Właściwości|właściwość]], indeksator musi zawierać conajmniej jeden [[C sharp/akcesory|akcesor]] (GET lub SET). Warto przypomnieć, że w akcesorach SET występuje niejawnie zadeklarowana zmienna przechowująca wartość przypisywaną do indeksatora.

Przykład

Poniżej przedstawiam program (aplikacja konsolowa), który pokazuje jak używać przedmiotowego mechanizmu:
using System;
using System.Collections.Generic;
using System.Text;

namespace programPrzykladowy
{
    class Program
    {
        static void Main(string[] args)
        {
            KlasaDniTygodnia objDniTygodnia = new KlasaDniTygodnia(); // <deklaracja i inicjalizacja obiektu />
            Console.WriteLine( objDniTygodnia[5] ); // <odwołanie się do tablicy w klasie za pomocą indeksatora />
            Console.ReadKey();
        }
    }

    // <przykładowa klasa implementująca indeksator>
    public class KlasaDniTygodnia
    {        

        private string[] nazwyDni; // <deklaracja tablicy />

	// <konstruktor>
        public KlasaDniTygodnia()
        {
            nazwyDni = new string[7]; // <inicjalizacja tablicy />

	    // <przypisanie wartości elementom tablicy>	
            nazwyDni[0] = "Poniedziałek";
            nazwyDni[1] = "Wtorek";
            nazwyDni[2] = "Środa";
            nazwyDni[3] = "Czwartek";
            nazwyDni[4] = "Piątek";
            nazwyDni[5] = "Sobota";
            nazwyDni[6] = "Niedziela";
	    // </przypisanie wartości elementom tablicy>	
        }
	// </konstruktor>

	// <indeksator>
        public string this[int indeks]
        {
	    // <akcesor zwracający wartosc tablicy>
            get
            {
                return this.nazwyDni[indeks - 1];
            }
	    // </akcesor zwracający wartosc tablicy>

	    // <akcesor zapisujący wartości do tablicy>
            set
            {
                this.nazwyDni[indeks-1] = value;
            }
	    // </akcesor zapisujący wartości do tablicy>
        }
	// </indeksator>
    }
    // </przykładowa klasa implementująca indeksator>


}

7 komentarzy

Nie zgadam się z " Istnieje tutaj jednak pewne ograniczenie, klasa zawierająca indeksator może mieć zadeklarowaną tylko jedną tablicę."
Klasa zawierająca indeksator może mieć wiele tablic, po prostu indeksator można zrobic na jednej tablicy, a do pozostałych odnosić się przez metody.

Tak wiem, zostałem górnikiem, ale robię to dla potomności!

@Marooned value to słowo kluczowe, więc zapewne przy takiej konstrukcji zostanie wyrzucony błąd.

Wiem, bo taką dokumentację sam tworzę. Myślałem, że to jakiś inny sposób :)

Teraz nie mam dostępu do VS więc nie sprawdzę, ale wydaje mi się, że kompilator powinien wyrzucić błąd. Standard komentarzy "zapożyczony" z pewnego projektu, w którym brałem udział. Moim zdaniem bardzo przejrzysty sposób komentowania kodu.

Komentarze XML po /// to mechanizm środowiska - tworzą one automatycznie dokumentację pisanego programu (opisy metod, parametrów, itd...).

set
{this.nazwyDni[indeks-1] = value;}

zmienna 'value' jest odgórnie narzucona? nigdzie się jej nie deklaruje?

A co się stanie w takim wypadku? [sorki, że sam nie sprawdzę, chwilowe problemy ze środowiskiem]

set
{int value;
this.nazwyDni[indeks-1] = value;
}

PS
ciekawy sposób komentarzy XMLowych - to jakiś Twój standard czy ogólny? Jak pisałem w VS 2k3 to tagi były tylko w komentarzach ///

Zmienna value jest deklarowana niejawnie i przechowuje wartość przypisywaną do indeksera. Jeśli zapiszemy:

objDniTygodnia[1] = "Monday";

to string "Monday" będzie przechowywany w zmiennej value.