Menu
Coddy logo textTech

Muster für Unveränderlichkeit

Teil des Abschnitts Objektorientierte Programmierung der C#-Journey von Coddy. Lektion 34 von 70.

Unveränderlichkeit (Immutability) führt die Kapselung zu ihrem logischen Extrem – sobald ein Objekt erstellt wurde, kann es sich nie mehr ändern. Dies eliminiert ganze Kategorien von Fehlern, da man sich nie Sorgen machen muss, dass etwas die Daten unerwartet ändert.

Der einfachste Weg, eine unveränderliche Klasse zu erstellen, besteht darin, readonly-Felder mit einem Konstruktor zu verwenden, der alle Werte setzt, und keine Setter bereitzustellen:

public class Point
{
    public readonly int X;
    public readonly int Y;
    
    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }
}

Sobald ein Point erstellt wurde, können seine Koordinaten nicht mehr geändert werden. Aber was ist, wenn Sie eine modifizierte Version benötigen? Anstatt das bestehende Objekt zu ändern, geben Sie ein neues zurück:

public Point Move(int deltaX, int deltaY)
{
    return new Point(X + deltaX, Y + deltaY);
}

Der ursprüngliche Punkt bleibt unverändert, während Sie einen neuen Punkt mit aktualisierten Werten erhalten. Dieses Muster wird in ganz .NET verwendet – Strings zum Beispiel sind unveränderlich. Wenn Sie ToUpper() aufrufen, erhalten Sie einen neuen String, anstatt den ursprünglichen zu ändern.

Unveränderliche Objekte sind von Natur aus threadsicher, da kein Code sie nach der Erstellung ändern kann. Sie sind zudem einfacher nachzuvollziehen, da man weiß, dass sich ihr Zustand niemals unerwartet ändern wird.

challenge icon

Aufgabe

Einfach

Erstellen wir ein unveränderliches Geldsystem, das demonstriert, wie Objekte so entworfen werden können, dass sie sich nach ihrer Erstellung niemals ändern. Du erstellst eine Money-Klasse, bei der jede Operation ein neues Objekt zurückgibt, anstatt das ursprüngliche zu verändern – ein Muster, das deinen Code sicherer und leichter nachvollziehbar macht.

Du organisierst deinen Code über zwei Dateien:

  • Money.cs: Erstelle eine unveränderliche Money-Klasse im Finance-Namespace. Dein Geldobjekt sollte Folgendes haben:
    • Zwei readonly-Felder: Amount (decimal) und Currency (string)
    • Einen Konstruktor, der beide Werte festlegt – sobald ein Money-Objekt erstellt wurde, kann es sich niemals ändern
    • Eine Methode Add(decimal value), die ein neues Money-Objekt mit dem erhöhten Betrag zurückgibt (gleiche Währung)
    • Eine Methode Subtract(decimal value), die ein neues Money-Objekt mit dem verringerten Betrag zurückgibt (gleiche Währung)
    • Eine Methode Convert(string newCurrency, decimal rate), die ein neues Money-Objekt zurückgibt, dessen Betrag mit dem Kurs multipliziert wurde und das die neue Währung verwendet
    • Eine Methode GetDisplay(), die einen String im Format "{Amount} {Currency}" zurückgibt
    Denke daran: Keine dieser Methoden sollte das ursprüngliche Objekt verändern – sie geben alle völlig neue Money-Instanzen zurück!
  • Program.cs: Demonstriere in deiner Hauptdatei die Unveränderlichkeit in Aktion. Erstelle zunächst ein Money-Objekt und führe dann Operationen darauf aus, während du Verweise sowohl auf das ursprüngliche Objekt als auch auf die Ergebnisse behältst. Dadurch wird bewiesen, dass sich das ursprüngliche Objekt auch nach mehreren Operationen niemals ändert.

Du erhältst vier Eingaben:

  • Anfangsbetrag (decimal)
  • Anfangswährung (string)
  • Hinzuzufügender Betrag (decimal)
  • Umrechnungskurs in EUR (decimal)

Gib die Ausgabe in diesem Format aus:

Original: {GetDisplay()}
After add: {GetDisplay()}
Original unchanged: {GetDisplay()}
Converted: {GetDisplay()}

Wenn die Eingaben beispielsweise 100.00, USD, 50.00 und 0.85 lauten, sollte die Ausgabe folgendermaßen aussehen:

Original: 100.00 USD
After add: 150.00 USD
Original unchanged: 100.00 USD
Converted: 127.50 EUR

Beachte, dass das ursprüngliche Money-Objekt auch nach dem Aufruf von 100.00 USD weiterhin Add() anzeigt – das ist Unveränderlichkeit! Die Methode Add() hat ein vollständig neues Objekt mit 150.00 USD erstellt und das ursprüngliche Objekt unverändert gelassen. Die Umrechnung wird am Ergebnis der Additionsoperation durchgeführt.

Probier es selbst

using System;
using Finance;

class Program
{
    public static void Main(string[] args)
    {
        // Eingaben lesen
        decimal initialAmount = Convert.ToDecimal(Console.ReadLine());
        string initialCurrency = Console.ReadLine();
        decimal amountToAdd = Convert.ToDecimal(Console.ReadLine());
        decimal conversionRate = Convert.ToDecimal(Console.ReadLine());

        // TODO: Erstelle ein initiales Money-Objekt mit dem ursprünglichen Betrag und der Währung

        // TODO: Gib das ursprüngliche Geld mit GetDisplay() aus

        // TODO: Rufe Add() auf dem Original auf und speichere das Ergebnis in einer neuen Variable

        // TODO: Gib das Ergebnis nach dem Hinzufügen mit GetDisplay() aus

        // TODO: Gib das Original erneut aus, um zu beweisen, dass es unverändert ist

        // TODO: Konvertiere das addierte Ergebnis unter Verwendung des Wechselkurses in EUR

        // TODO: Gib das konvertierte Geld mit GetDisplay() aus
    }
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-C#-Compiler