C# Academy · Lekcja

Indeksery

Uzyskuj dostęp do obiektów za pomocą składni podobnej do tablicowej.

Lekcja 4 z 413 kroki

Indeksery to bezpłatna lekcja C# Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C# Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C# Academy zawiera 4 lekcji w sumie.

Czym jest indeksator

Indeksator pozwala uzyskiwać dostęp do obiektu za pomocą składni [ ], podobnie jak do tablicy. Definiuje się go za pomocą this[...]. Doskonale nadaje się do klas przypominających kolekcje.

using System;

class Week
{
    private string[] _days = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };

    public string this[int index] => _days[index];
}

class Program
{
    static void Main()
    {
        var w = new Week();
        Console.WriteLine(w[0]);
        Console.WriteLine(w[6]);
    }
}

Składnia indeksatora

Indeksator przypomina właściwość, ale korzysta z this i przyjmuje listę parametrów w nawiasach kwadratowych. Ma akcesor get oraz opcjonalnie set.

using System;

class Scores
{
    private int[] _data = new int[5];

    public int this[int i]
    {
        get { return _data[i]; }
        set { _data[i] = value; }
    }
}

class Program
{
    static void Main()
    {
        var s = new Scores();
        s[0] = 90;
        s[1] = 75;
        Console.WriteLine(s[0] + ", " + s[1]);
    }
}

Odczyt i zapis za pomocą indeksatora

Getter i setter pozwalają przypisywać oraz odczytywać elementy tak jak w tablicy, podczas gdy klasa kontroluje sposób ich przechowywania.

using System;

class Grid
{
    private int[] _cells = new int[3];

    public int this[int i]
    {
        get => _cells[i];
        set => _cells[i] = value;
    }
}

class Program
{
    static void Main()
    {
        var g = new Grid();
        for (int i = 0; i < 3; i++) g[i] = i * 10;
        Console.WriteLine(g[0] + ", " + g[1] + ", " + g[2]);
    }
}

Walidacja w indeksatorze

Indeksator jest po prostu kodem, dlatego można w nim zweryfikować indeks i zgłosić zrozumiały błąd przy dostępie poza zakresem.

using System;

class SafeList
{
    private int[] _data = new int[3];

    public int this[int i]
    {
        get
        {
            if (i < 0 || i >= _data.Length)
                throw new IndexOutOfRangeException("Bad index: " + i);
            return _data[i];
        }
        set { _data[i] = value; }
    }
}

class Program
{
    static void Main()
    {
        var list = new SafeList();
        list[1] = 42;
        Console.WriteLine(list[1]);
    }
}

Indeksatory z kluczem tekstowym

Parametry indeksatora nie są ograniczone do typu int. Klucz typu string zmienia klasę w mechanizm wyszukiwania przypominający słownik.

using System;
using System.Collections.Generic;

class Config
{
    private Dictionary<string, string> _map = new Dictionary<string, string>();

    public string this[string key]
    {
        get => _map.ContainsKey(key) ? _map[key] : "(none)";
        set => _map[key] = value;
    }
}

class Program
{
    static void Main()
    {
        var c = new Config();
        c["theme"] = "dark";
        Console.WriteLine(c["theme"]);
        Console.WriteLine(c["missing"]);
    }
}

Wiele parametrów

Indeksator może przyjmować więcej niż jeden parametr, co doskonale sprawdza się w przypadku macierzy lub siatek 2D dostępnych jako matrix[row, col].

using System;

class Matrix
{
    private int[,] _data = new int[2, 2];

    public int this[int row, int col]
    {
        get => _data[row, col];
        set => _data[row, col] = value;
    }
}

class Program
{
    static void Main()
    {
        var m = new Matrix();
        m[0, 0] = 1;
        m[1, 1] = 9;
        Console.WriteLine(m[0, 0] + ", " + m[1, 1]);
    }
}

Indeksatory tylko do odczytu

Proszę pominąć setter, aby utworzyć indeksator tylko do odczytu, który udostępnia dane bez zezwalania na ich zewnętrzną modyfikację.

using System;

class Fibonacci
{
    public int this[int n]
    {
        get
        {
            int a = 0, bv = 1;
            for (int i = 0; i < n; i++)
            {
                int t = a + bv;
                a = bv;
                bv = t;
            }
            return a;
        }
    }
}

class Program
{
    static void Main()
    {
        var fib = new Fibonacci();
        Console.WriteLine(fib[7]);
    }
}

Indeksatory a właściwości

Do właściwości uzyskuje się dostęp po nazwie (obj.Name), a do indeksatora po kluczu (obj[key]). Indeksatora należy używać, gdy obiekt zachowuje się jak kolekcja.

using System;

class Inventory
{
    private int[] _stock = new int[4];
    public int Total => _stock.Length;          // property
    public int this[int slot]                    // indexer
    {
        get => _stock[slot];
        set => _stock[slot] = value;
    }
}

class Program
{
    static void Main()
    {
        var inv = new Inventory();
        inv[2] = 15;
        Console.WriteLine("Slot 2: " + inv[2] + ", Total slots: " + inv.Total);
    }
}

Przeciążone indeksatory

Można definiować wiele indeksatorów z różnymi typami parametrów, a kompilator wybiera indeksator pasujący do użytych argumentów.

using System;
using System.Collections.Generic;

class People
{
    private List<string> _names = new List<string> { "Ann", "Bob", "Cara" };

    public string this[int i] => _names[i];
    public int this[string name] => _names.IndexOf(name);
}

class Program
{
    static void Main()
    {
        var p = new People();
        Console.WriteLine(p[1]);
        Console.WriteLine(p["Cara"]);
    }
}

Iterowanie po obiekcie indeksowanym

Połączenie indeksatora z właściwością przechowującą liczbę elementów pozwala w naturalny sposób iterować po niestandardowej kolekcji.

using System;

class Ring
{
    private int[] _data = { 10, 20, 30 };
    public int Count => _data.Length;
    public int this[int i] => _data[i % _data.Length];
}

class Program
{
    static void Main()
    {
        var ring = new Ring();
        for (int i = 0; i < 5; i++)
            Console.Write(ring[i] + " ");
        Console.WriteLine();
    }
}

Połączenie elementów

Indeksatory sprawiają, że klasy opakowujące przypominają natywne kolekcje, ukrywając szczegóły przechowywania danych za znajomą składnią nawiasów kwadratowych.

using System;
using System.Collections.Generic;

class Phonebook
{
    private Dictionary<string, string> _book = new Dictionary<string, string>();

    public string this[string name]
    {
        get => _book.TryGetValue(name, out var num) ? num : "unknown";
        set => _book[name] = value;
    }
}

class Program
{
    static void Main()
    {
        var pb = new Phonebook();
        pb["Alice"] = "555-1234";
        Console.WriteLine("Alice: " + pb["Alice"]);
        Console.WriteLine("Zed: " + pb["Zed"]);
    }
}

Szybkie sprawdzenie

Proszę sprawdzić zrozumienie indeksatorów.

Podsumowanie

Indeksator korzysta z this[...], aby zapewnić klasie dostęp przypominający dostęp do tablicy. Obsługuje akcesory get/set, dowolny typ parametru (int, string lub wiele parametrów), walidację, przeciążanie oraz warianty tylko do odczytu. Indeksatorów należy używać w klasach przypominających kolekcje, a nazwanych właściwości — w przypadku odrębnych atrybutów.

using System;

class Demo
{
    private int[] _v = new int[3];
    public int this[int i]
    {
        get => _v[i];
        set => _v[i] = value;
    }
}

class Program
{
    static void Main()
    {
        var d = new Demo();
        d[0] = 100;
        Console.WriteLine(d[0]);
    }
}
Bezpłatny start

Ucz się C# dzięki korepetycjom AI — za darmo

Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.

Kursy
93
Lekcje
346

Często zadawane pytania

Czy lekcja „Indeksery” jest bezpłatna?

Tak — pełny tekst „Indeksery” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C# Academy, przejdź na CoddyKit PRO. Kurs C# Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Indeksery”?

Uzyskuj dostęp do obiektów za pomocą składni podobnej do tablicowej. Ćwiczysz C# Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć C# Academy?

Nie wymagamy żadnego doświadczenia. C# Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Indeksery”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji C# Academy?

Tak. Każda lekcja C# Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Właściwości implementowane automatycznie
  2. Pełne właściwości z polami zapasowymi
  3. Elementy składowe z treścią wyrażeniową
  4. Indeksery
← Powrót do C# Academy