Sobes.tech
Junior

Wat zijn indices in C#? Welke soorten indices bestaan er en hebt u ze in de praktijk gebruikt?

sobes.tech AI

Antwoord van AI

Indexatoren in C# stellen die Möglichkeit dar, auf eine Instanz einer Klasse oder Struktur wie auf ein Array zuzugreifen, unter Verwendung der Syntax []. Sie sind nicht statisch und überladen den [] Operator.

Indexatoren

Indexatoren ermöglichen die Definition von Zugriffslogik auf Elemente einer Sammlung oder Datenstruktur innerhalb einer Klasse.

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

    // Indexator, der das Abrufen oder Setzen eines Elements nach Index erlaubt
    public string this[int index]
    {
        get
        {
            // Grenzprüfung
            if (index >= 0 && index < data.Length)
            {
                return data[index];
            }
            else
            {
                throw new IndexOutOfRangeException();
            }
        }
        set
        {
            // Grenzprüfung
            if (index >= 0 && index < data.Length)
            {
                data[index] = value;
            }
            else
            {
                throw new IndexOutOfRangeException();
            }
        }
    }
}

Typen der Indexator-Parameter

Indexatoren können beliebige Mengen an Parametern beliebigen Typs annehmen, nicht nur ganze Zahlen.

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

    // Indexator mit String-Parameter
    public string this[string key]
    {
        get
        {
            if (_dictionary.ContainsKey(key))
            {
                return _dictionary[key];
            }
            else
            {
                return null; // Oder eine Ausnahme werfen
            }
        }
        set
        {
            _dictionary[key] = value;
        }
    }
}

Überladung von Indexatoren

Es ist möglich, überladene Indexatoren 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];
    }

    // Indexator mit zwei ganzzahligen Parametern
    public int this[int row, int col]
    {
        get
        {
            // Grenzprüfung
            if (row >= 0 && row < data.GetLength(0) && col >= 0 && col < data.GetLength(1))
            {
                return data[row, col];
            }
            else
            {
                throw new IndexOutOfRangeException();
            }
        }
        set
        {
            // Grenzprüfung
            if (row >= 0 && row < data.GetLength(0) && col >= 0 && col < data.GetLength(1))
            {
                data[row, col] = value;
            }
            else
            {
                throw new IndexOutOfRangeException();
            }
        }
    }
}

Aralık indeksleri (Ranges & Indices)

C# 8.0 ile System.Index ve System.Range yeni turlari tanıtildi, bunlar koleksiyonların sonundan elementlere erişim (^) ve alt diziler alma (..) için sözdizimi sağlar. Bu kavramlar "indeksler" olarak adlandırılır, ancak klasik indeksatorlardan farklıdırlar.

using System;

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

        // System.Index kullanarak sondan erişim
        Index last = ^1; // son elementin indeksi
        Console.WriteLine(words[last]); // dog

        // System.Range kullanarak alt dizi alma
        Range middle = 1..4; // 1-indeksinden 4-igacha (4 dahil değil)
        string[] subset = words[middle]; // {"quick", "brown", "fox"}

        // System.Index ile Range
        Range fromEnd = ^3..; // sondan üçüncü elementten başlayıp sona kadar
        string[] suffix = words[fromEnd]; // {"the", "lazy", "dog"}
    }
}

Praktische Anwendung

Ich habe Indexatoren aktiv beim Erstellen eigener Sammlungsklassen oder Wrapper über bestehende verwendet, um den Zugriff auf Daten intuitiver zu gestalten. Zum Beispiel:

  • Entwicklung von Klassen, die Matrizen oder mehrdimensionale Daten repräsentieren, bei denen der Zugriff nach Koordinaten matrix[row, col] logisch ist.
  • Erstellung von Wrappers über Dictionary<> oder andere Sammlungen, bei denen der Zugriff nach Schlüssel über den Indexator die Lesbarkeit des Codes verbessert.
  • In einfachen Sammlungen, bei denen eine syntaktisch bequeme Zugriffsmöglichkeit wie bei Arrays erforderlich ist.

Range-Indizes (System.Index und System.Range) wurden für einen prägnanteren Zugriff auf Teile von Arrays oder Listen verwendet, was besonders bei der Arbeit mit Substrings oder Teilmengen von Daten aus einer Sammlung nützlich ist.