Was sind Indizes in C#? Welche Arten von Indizes gibt es und haben Sie sie in der Praxis verwendet?
sobes.tech KI
Antwort von AI
Indexierer in C# ermöglichen den Zugriff auf eine Instanz einer Klasse oder Struktur wie auf ein Array, unter Verwendung der Syntax []. Sie sind nicht statisch und überladen den Operator [].
Indexierer
Indexierer erlauben die Definition der Zugrifflogik auf Elemente einer Sammlung oder Datenstruktur innerhalb einer Klasse.
public class MyCollection
{
private string[] data = new string[10];
// Indexierer, der das Abrufen oder Setzen eines Elements nach Index ermöglicht
public string this[int index]
{
get
{
// Grenzwertprüfung
if (index >= 0 && index < data.Length)
{
return data[index];
}
else
{
throw new IndexOutOfRangeException();
}
}
set
{
// Grenzwertprüfung
if (index >= 0 && index < data.Length)
{
data[index] = value;
}
else
{
throw new IndexOutOfRangeException();
}
}
}
}
Parameterarten von Indexierern
Indexierer können beliebige Mengen an Parametern beliebigen Typs akzeptieren, nicht nur ganze Zahlen.
public class DictionaryLike
{
private Dictionary<string, string> _dictionary = new Dictionary<string, string>();
// Indexierer mit Parameter vom Typ string
public string this[string key]
{
get
{
if (_dictionary.ContainsKey(key))
{
return _dictionary[key];
}
else
{
return null; // Oder Ausnahme werfen
}
}
set
{
_dictionary[key] = value;
}
}
}
Überladung von Indexierern
Es ist möglich, überladene Indexierer mit unterschiedlichen Signaturen (Parametersets und -typen) zu erstellen.
public class Matrix
{
private int[,] data;
public Matrix(int rows, int cols)
{
data = new int[rows, cols];
}
// Indexierer mit zwei Ganzzahlparametern
public int this[int row, int col]
{
get
{
// Grenzwertprüfung
if (row >= 0 && row < data.GetLength(0) && col >= 0 && col < data.GetLength(1))
{
return data[row, col];
}
else
{
throw new IndexOutOfRangeException();
}
}
set
{
// Grenzwertprüfung
if (row >= 0 && row < data.GetLength(0) && col >= 0 && col < data.GetLength(1))
{
data[row, col] = value;
}
else
{
throw new IndexOutOfRangeException();
}
}
}
}
Bereichsindizes (Ranges & Indizes)
In C# 8.0 wurden die neuen Typen System.Index und System.Range eingeführt, die die Syntax für den Zugriff auf Elemente vom Ende der Sammlung (^) und für das Erhalten von Teilbereichen (..) ermöglichen. Diese Begriffe werden oft "Indizes" genannt, unterscheiden sich jedoch von klassischen Indexern.
using System;
public class ArrayExample
{
public static void Main(string[] args)
{
string[] words = { "the", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog" };
// Verwendung von System.Index für den Zugriff vom Ende
Index last = ^1; // Index des letzten Elements
Console.WriteLine(words[last]); // dog
// Verwendung von System.Range für das Erhalten eines Teilbereichs
Range middle = 1..4; // Elemente von Index 1 bis (aber nicht einschließlich) Index 4
string[] subset = words[middle]; // {"quick", "brown", "fox"}
// Range mit Verwendung von System.Index
Range fromEnd = ^3..; // vom dritten vom Ende bis zum Ende
string[] suffix = words[fromEnd]; // {"the", "lazy", "dog"}
}
}
Praktische Anwendung
Ich habe Indexierer aktiv genutzt, um eigene Sammlungsklassen oder Wrapper über bestehende Sammlungen zu erstellen, um einen intuitiveren Datenzugriff zu ermöglichen. Zum Beispiel:
- Entwicklung von Klassen, die Matrizen oder mehrdimensionale Daten repräsentieren, bei denen der Zugriff nach Koordinaten
matrix[row, col]sinnvoll ist. - Erstellung von Wrappers über
Dictionary<>oder andere Sammlungen, bei denen der Zugriff über Schlüssel durch den Indexer die Lesbarkeit des Codes verbessert. - In einfachen Sammlungen, bei denen eine syntaktisch bequeme Zugriffssyntax, ähnlich einem Array, erforderlich ist.
Ich habe Range-Indizes (System.Index und System.Range) verwendet, um einen prägnanteren Zugriff auf Teile von Arrays oder Listen zu ermöglichen, was besonders bei der Arbeit mit Substrings oder Teilmengen aus einer Sammlung nützlich ist.