Sobes.tech
Junior

Čo sú indexy v C#? Aké typy indexov existujú a či ste ich používali v praxi?

sobes.tech AI

Odpoveď od AI

Indexátory v C# umožňujú pristup k inštancii triedy alebo štruktúry ako k poľu pomocou syntaxe []. Nie sú statické a prepísavajú operátor [].

Indexátory

Indexátory umožňujú definovať logiku prístupu k prvkom kolekcie alebo dátovej štruktúre vnútri triedy.

public class MyCollection
{
    private string[] data = new string[10];

    // Indexátor, ktorý umožňuje získavať alebo nastavovať prvok podľa indexu
    public string this[int index]
    {
        get
        {
            // Kontrola hraníc
            if (index >= 0 && index < data.Length)
            {
                return data[index];
            }
            else
            {
                throw new IndexOutOfRangeException();
            }
        }
        set
        {
            // Kontrola hraníc
            if (index >= 0 && index < data.Length)
            {
                data[index] = value;
            }
            else
            {
                throw new IndexOutOfRangeException();
            }
        }
    }
}

Typy parametrov indexátorov

Indexátory môžu prijímať ľubovoľný počet parametrov akéhokoľvek typu, nie sú obmedzené len na celočíselné typy.

public class DictionaryLike
{
    private Dictionary<string, string> _dictionary = new Dictionary<string, string>();

    // Indexátor s parametrom typu string
    public string this[string key]
    {
        get
        {
            if (_dictionary.ContainsKey(key))
            {
                return _dictionary[key];
            }
            else
            {
                return null; // Alebo vyhodiť výnimku
            }
        }
        set
        {
            _dictionary[key] = value;
        }
    }
}

Preťaženie indexátorov

Je možné vytvárať preťažené indexátory s rôznymi signatúrami (sada a typy parametrov).

public class Matrix
{
    private int[,] data;

    public Matrix(int rows, int cols)
    {
        data = new int[rows, cols];
    }

    // Indexátor s dvomi celými číslami ako parametrami
    public int this[int row, int col]
    {
        get
        {
            // Kontrola hraníc
            if (row >= 0 && row < data.GetLength(0) && col >= 0 && col < data.GetLength(1))
            {
                return data[row, col];
            }
            else
            {
                throw new IndexOutOfRangeException();
            }
        }
        set
        {
            // Kontrola hraníc
            if (row >= 0 && row < data.GetLength(0) && col >= 0 && col < data.GetLength(1))
            {
                data[row, col] = value;
            }
            else
            {
                throw new IndexOutOfRangeException();
            }
        }
    }
}

Rozsahové indexy (Ranges & Indices)

V C# 8.0 boli zavedené nové typy System.Index a System.Range, ktoré umožňujú používať syntax pre prístup k prvkom od konca kolekcie (^) a na získanie podrozsahu (..). Tieto pojmy sa často nazývajú "indexy", ale odlišujú sa od klasických indexátorov.

using System;

public class ArrayExample
{
    public static void Main(string[] args)
    {
        string[] words = { "the", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog" };

        // Použitie System.Index na prístup od konca
        Index last = ^1; // Index posledného prvku
        Console.WriteLine(words[last]); // dog

        // Použitie System.Range na získanie podrozsahu
        Range middle = 1..4; // Prvky od indexu 1 do (ale nie vrátane) 4
        string[] subset = words[middle]; // {"quick", "brown", "fox"}

        // Range s použitím System.Index
        Range fromEnd = ^3..; // od tretieho od konca do konca
        string[] suffix = words[fromEnd]; // {"the", "lazy", "dog"}
    }
}

Praktické využitie

Aktívne som používal indexátory pri vytváraní vlastných kolekčných tried alebo obalov nad existujúcimi na poskytnutie intuitívneho prístupu k dátam. Napríklad:

  • Vývoj tried, ktoré predstavujú matice alebo viacrozmerné dáta, kde je prístup podľa súradníc matrix[row, col] logický.
  • Vytváranie obalov nad Dictionary<> alebo inými kolekciami, kde prístup podľa kľúča cez indexátor zlepšoval čitateľnosť kódu.
  • V jednoduchých kolekciách, kde bola potrebná syntaktická pohodlnosť prístupu, podobne ako pri poli.

Rozsahové indexy (System.Index a System.Range) som používal na stručnejší prístup k častiam polí alebo zoznamov, čo je obzvlášť užitočné pri práci s podreťazcami alebo čiastočnými dátami z kolekcie.