Kas yra indeksai C#? Kokie indeksų tipai egzistuoja ir ar juos naudojote praktikoje?
sobes.tech AI
Atsakymas iš AI
C# indeksatoriai leidžia kreiptis į klasės ar struktūros egzempliorių kaip į masyvą, naudojant sintaksę []. Jie nėra statiniai ir perkrauna operatorių [].
Indeksatoriai
Indeksatoriai leidžia apibrėžti prieigos logiką prie kolekcijos elementų ar duomenų struktūros klasėje.
public class MyCollection
{
private string[] data = new string[10];
// Indeksatorius, leidžiantis gauti arba nustatyti elementą pagal indeksą
public string this[int index]
{
get
{
// Ribų patikrinimas
if (index >= 0 && index < data.Length)
{
return data[index];
}
else
{
throw new IndexOutOfRangeException();
}
}
set
{
// Ribų patikrinimas
if (index >= 0 && index < data.Length)
{
data[index] = value;
}
else
{
throw new IndexOutOfRangeException();
}
}
}
}
Indeksatorių tipai
Indeksatoriai gali priimti bet kokį parametrų skaičių ir tipą, neapsiribojant tik sveikųjų skaičių tipais.
public class DictionaryLike
{
private Dictionary<string, string> _dictionary = new Dictionary<string, string>();
// Indeksatorius su string tipo parametru
public string this[string key]
{
get
{
if (_dictionary.ContainsKey(key))
{
return _dictionary[key];
}
else
{
return null; // arba išmesti išimtį
}
}
set
{
_dictionary[key] = value;
}
}
}
Perkrauta indeksatorių
Galima kurti perkrautus indeksatorius su skirtingomis parašomis (parametrų rinkiniu ir tipais).
public class Matrix
{
private int[,] data;
public Matrix(int rows, int cols)
{
data = new int[rows, cols];
}
// Indeksatorius su dviem sveikųjų skaičių parametrais
public int this[int row, int col]
{
get
{
// Ribų patikrinimas
if (row >= 0 && row < data.GetLength(0) && col >= 0 && col < data.GetLength(1))
{
return data[row, col];
}
else
{
throw new IndexOutOfRangeException();
}
}
set
{
// Ribų patikrinimas
if (row >= 0 && row < data.GetLength(0) && col >= 0 && col < data.GetLength(1))
{
data[row, col] = value;
}
else
{
throw new IndexOutOfRangeException();
}
}
}
}
Intervaliniai indeksai (Ranges & Indices)
Nuo C# 8.0 buvo įvesti nauji System.Index ir System.Range tipai, leidžiantys naudoti sintaksę, skirtą prieigai prie elementų iš kolekcijos pabaigos (^) ir gauti dalinius diapazonus (..). Šie konceptai dažnai vadinami "indeksais", tačiau jie skiriasi nuo klasikinių indeksatorių.
using System;
public class ArrayExample
{
public static void Main(string[] args)
{
string[] words = { "the", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog" };
// Naudojant System.Index prieigai iš pabaigos
Index last = ^1; // Paskutinio elemento indeksas
Console.WriteLine(words[last]); // dog
// Naudojant System.Range gauti dalinį diapazoną
Range middle = 1..4; // Elementai nuo indekso 1 iki (neįskaitant) indekso 4
string[] subset = words[middle]; // {"quick", "brown", "fox"}
// Range su System.Index
Range fromEnd = ^3..; // nuo trečio nuo pabaigos iki pabaigos
string[] suffix = words[fromEnd]; // {"the", "lazy", "dog"}
}
}
Praktinis taikymas
Aš aktyviai naudoju indeksatorius kuriant savo kolekcijų klases ar apvalkale ant esamų, siekiant suteikti intuityvesnį duomenų prieigos būdą. Pavyzdžiui:
- Klasės, reprezentuojančios matricą ar daugiamačius duomenis, kur prieiga pagal koordinates
matrix[row, col]buvo logiška. - Apvalkale ant
Dictionary<>ar kitų kolekcijų, kur prieiga pagal raktą per indeksatorių pagerina kodo skaitomumą. - Paprasčiose kolekcijose, kur reikėjo sintaksės patogumo prieigos, panašios į masyvą.
Intervaliniai indeksai (System.Index ir System.Range) naudojami patogesnei prieigai prie masyvų ar sąrašų dalių, ypač dirbant su eilutėmis ar dalinėmis kolekcijų dalimis.