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>
}
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.