Übersicht: Indexer und Operator Overloading in C#

Diese Übersicht erklärt zwei fortgeschrittene, aber sehr nützliche Konzepte in C#: - Indexer - Operator Overloading

Beide helfen dabei, eigene Klassen natürlicher und intuitiver benutzbar zu machen.


1. Indexer

Ein Indexer erlaubt es, auf Objekte so zuzugreifen, als wären sie ein Array oder eine Liste.

Beispiel:

klasse[3]

statt:

klasse.Get(3)

Grundstruktur eines Indexers

class MyCollection
{
    private int[] data = new int[10];
 
    public int this[int index]
    {
        get { return data[index]; }
        set { data[index] = value; }
    }
}

Verwendung:

MyCollection c = new MyCollection();
c[0] = 42;
Console.WriteLine(c[0]); // 42

Warum Indexer verwenden?

  • Der Code wird lesbarer
  • Die Klasse fühlt sich an wie eine eingebaute Datenstruktur
  • Ideal für:
    • Sammlungen
    • Container-Klassen
    • Wrapper um Arrays oder Listen

2. Indexer mit mehreren Parametern

class Matrix
{
    private int[,] data = new int[3,3];
 
    public int this[int row, int col]
    {
        get { return data[row, col]; }
        set { data[row, col] = value; }
    }
}

Verwendung:

Matrix m = new Matrix();
m[1,2] = 5;
Console.WriteLine(m[1,2]);

Sehr praktisch für: - Matrizen - Spielfelder - 2D-Koordinatensysteme


3. Operator Overloading

Mit Operator Overloading kannst du festlegen, wie Operatoren wie +, -, *, == usw. für eigene Klassen funktionieren.

Beispiel ohne Overloading:

Vector v3 = v1.Add(v2);

Mit Overloading:

Vector v3 = v1 + v2;

Beispiel: Vektoraddition

class Vector2D
{
    public int X { get; set; }
    public int Y { get; set; }
 
    public Vector2D(int x, int y)
    {
        X = x;
        Y = y;
    }
 
    public static Vector2D operator +(Vector2D a, Vector2D b)
    {
        return new Vector2D(a.X + b.X, a.Y + b.Y);
    }
}

Verwendung:

Vector2D v1 = new Vector2D(2, 3);
Vector2D v2 = new Vector2D(4, 1);
 
Vector2D v3 = v1 + v2;

4. Vergleichsoperatoren überladen

class Score
{
    public int Points { get; set; }
 
    public Score(int points)
    {
        Points = points;
    }
 
    public static bool operator >(Score a, Score b)
    {
        return a.Points > b.Points;
    }
 
    public static bool operator <(Score a, Score b)
    {
        return a.Points < b.Points;
    }
}

Verwendung:

Score s1 = new Score(50);
Score s2 = new Score(75);
 
if (s2 > s1)
    Console.WriteLine("s2 ist besser!");

Hinweis: > Wenn > überladen wird, muss auch < überladen werden.


5. Typische Einsatzgebiete

Indexer

  • Spielfelder (z.B. TicTacToe, Schach, Sudoku)
  • Tabellen
  • Inventarsysteme
  • Eigene Listen-Klassen

Operator Overloading

  • Vektoren und Matrizen
  • Geldbeträge
  • Punkte- oder Bewertungssysteme
  • Mathematische Modelle

6. Gute Regeln

  1. Operatoren sollten das tun, was man intuitiv erwartet.
  2. Kein „Überraschungsverhalten” einbauen.
  3. Lesbarkeit geht vor Cleverness.
  4. Nicht alles überladen — nur wenn es sinnvoll ist.

7. Vergleich: Normal vs. mit Operator Overloading

Ohne:

Vector2D result = v1.Add(v2);

Mit:

Vector2D result = v1 + v2;

Ohne:

board.GetCell(1,2);

Mit Indexer:

board[1,2];