Co jsou indexy v C#? Jaké typy indexů existují a používal jste je v praxi?
sobes.tech AI
Odpověď od AI
Indexery v C# umožňují přístup k instanci třídy nebo struktury jako k poli pomocí syntaxe []. Nejsou statické a přetěžují operátor [].
Indexery
Indexery umožňují definovat logiku přístupu k prvkům kolekce nebo datové struktury uvnitř třídy.
public class MyCollection
{
private string[] data = new string[10];
// Indexer umožňující získat nebo nastavit prvek podle indexu
public string this[int index]
{
get
{
// Kontrola hranic
if (index >= 0 && index < data.Length)
{
return data[index];
}
else
{
throw new IndexOutOfRangeException();
}
}
set
{
// Kontrola hranic
if (index >= 0 && index < data.Length)
{
data[index] = value;
}
else
{
throw new IndexOutOfRangeException();
}
}
}
}
Typy parametrů indexerů
Indexery mohou přijímat libovolné množství parametrů jakéhokoliv typu, nikoliv pouze celočíselné.
public class DictionaryLike
{
private Dictionary<string, string> _dictionary = new Dictionary<string, string>();
// Indexer s parametrem typu string
public string this[string key]
{
get
{
if (_dictionary.ContainsKey(key))
{
return _dictionary[key];
}
else
{
return null; // nebo vyvolat výjimku
}
}
set
{
_dictionary[key] = value;
}
}
}
Přetížení indexerů
Lze vytvářet přetížené indexery s různými signaturami (sady a typy parametrů).
public class Matrix
{
private int[,] data;
public Matrix(int rows, int cols)
{
data = new int[rows, cols];
}
// Indexer se dvěma celočíselnými parametry
public int this[int row, int col]
{
get
{
// Kontrola hranic
if (row >= 0 && row < data.GetLength(0) && col >= 0 && col < data.GetLength(1))
{
return data[row, col];
}
else
{
throw new IndexOutOfRangeException();
}
}
set
{
// Kontrola hranic
if (row >= 0 && row < data.GetLength(0) && col >= 0 && col < data.GetLength(1))
{
data[row, col] = value;
}
else
{
throw new IndexOutOfRangeException();
}
}
}
}
Rozsahy indexů (Ranges & Indices)
V C# 8.0 byly zavedeny nové typy System.Index a System.Range, které umožňují používat syntax pro přístup k prvkům od konce kolekce (^) a pro získání podmnožiny (..). Tyto pojmy jsou často označovány jako "indexy", ale liší se od klasických indexátorů.
using System;
public class ArrayExample
{
public static void Main(string[] args)
{
string[] words = { "the", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog" };
// Použití System.Index pro přístup od konce
Index last = ^1; // index posledního prvku
Console.WriteLine(words[last]); // dog
// Použití System.Range pro získání podmnožiny
Range middle = 1..4; // prvky od indexu 1 do (ale nevčetně) indexu 4
string[] subset = words[middle]; // {"quick", "brown", "fox"}
// Range s použitím System.Index
Range fromEnd = ^3..; // od třetího od konce do konce
string[] suffix = words[fromEnd]; // {"the", "lazy", "dog"}
}
}
Praktické použití
Aktivně jsem používal indexery při tvorbě vlastních tříd kolekcí nebo obalů nad existujícími kolekcemi pro poskytnutí intuitivnějšího přístupu k datům. Například:
- Vývoj tříd reprezentujících matice nebo vícerozměrná data, kde byl přístup podle souřadnic
matrix[row, col]logický. - Vytváření obalů nad
Dictionary<>nebo jinými kolekcemi, kde přístup podle klíče přes indexer zlepšoval čitelnost kódu. - V jednoduchých kolekcích, kde bylo potřeba syntakticky pohodlný přístup, podobně jako u pole.
Používal jsem rozsahové indexy (System.Index a System.Range) pro stručnější přístup k částem polí nebo seznamů, což je zvláště užitečné při práci s podřetězci nebo částečnými daty z kolekce.