Wertgleichheit und Dekonstruktion
Verstehen Sie die strukturelle Gleichheit von Records, überschreiben Sie Equals/GetHashCode und verwenden Sie Dekonstruktionsmuster.
Wertgleichheit und Dekonstruktion ist eine kostenlose C# Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des C# Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der C# Academy-Kurs umfasst insgesamt 4 Lektionen.
Tiefgehende Betrachtung der Record-Gleichheit
Records generieren automatisch Equals, GetHashCode sowie die Operatoren ==/!=, die alle Eigenschaften strukturell vergleichen. Wenn Sie verstehen, wie das funktioniert, können Sie Records korrekt verwenden und bei Bedarf überschreiben.
Funktionsweise der automatisch generierten Gleichheit
Der Compiler generiert Code, der jede Eigenschaft mithilfe von EqualityComparer<T>.Default vergleicht. Bei Eigenschaften von Referenztypen ist dies deren eigenes Equals – nicht Referenzgleichheit.
public record Address(string Street, string City);
public record Person(string Name, Address HomeAddress);
var a = new Person("Alice", new Address("123 Main", "NYC"));
var b = new Person("Alice", new Address("123 Main", "NYC"));
Console.WriteLine(a == b); // True — deep structural equality
// Equality checks:
// Name: "Alice" == "Alice" ✓
// HomeAddress: compares Address properties recursively ✓Generierte Gleichheit überschreiben
Sie können Equals und GetHashCode für einen Record überschreiben, wenn Sie eine eigene Gleichheitslogik benötigen – beispielsweise, um nur eine Teilmenge der Eigenschaften zu vergleichen.
public record Customer(int Id, string Name, string Email)
{
// Consider customers equal if they have the same ID,
// regardless of name or email changes
public virtual bool Equals(Customer? other)
=> other is not null && Id == other.Id;
public override int GetHashCode() => Id.GetHashCode();
}Records in Sammlungen
Da Records IEquatable<T> mit struktureller Gleichheit implementieren, funktionieren sie korrekt als Wörterbuchschlüssel, in HashSets sowie mit LINQ-Methoden wie Distinct und GroupBy.
public record Tag(string Name, string Color);
var tags = new List<Tag>
{
new("C#", "blue"), new("C#", "blue"), new("dotnet", "purple")
};
var unique = tags.Distinct().ToList(); // [Tag(C#, blue), Tag(dotnet, purple)]
var set = new HashSet<Tag>(tags);
set.Contains(new Tag("C#", "blue")); // trueDekonstruktion: Grundlagen
Positionale Records generieren automatisch eine Deconstruct-Methode mit out-Parametern für jede positionale Eigenschaft. Dadurch wird ein Entpacken ähnlich wie bei Tupeln ermöglicht.
public record Point(double X, double Y);
public record RGB(byte R, byte G, byte B);
var p = new Point(3.0, 4.0);
var (x, y) = p; // deconstruct
Console.WriteLine($"{x}, {y}");
var color = new RGB(255, 128, 0);
var (r, g, b) = color;
Console.WriteLine($"R={r}, G={g}, B={b}");Dekonstruktion beim Pattern Matching
In switch-Ausdrücken dekonstruierte Records ermöglichen leistungsfähiges positionales Pattern Matching.
public record Point(int X, int Y);
string Classify(Point p) => p switch
{
(0, 0) => "Origin",
(int x, 0) => $"X-axis at {x}",
(0, int y) => $"Y-axis at {y}",
(int x, int y) when x == y => $"Diagonal at {x}",
(int x, int y) => $"Point ({x}, {y})"
};
Console.WriteLine(Classify(new Point(0, 0))); // Origin
Console.WriteLine(Classify(new Point(3, 3))); // Diagonal at 3Benutzerdefinierte Deconstruct-Methoden
Nicht-positionale Records (und jede Klasse) können manuell eine Deconstruct-Methode hinzufügen. Erweiterungsmethoden können die Dekonstruktion auch für vorhandene Typen ergänzen.
public class Temperature
{
public double Celsius { get; }
public Temperature(double c) => Celsius = c;
// Manual Deconstruct
public void Deconstruct(out double celsius, out double fahrenheit)
{
celsius = Celsius;
fahrenheit = Celsius * 9 / 5 + 32;
}
}
var t = new Temperature(100);
var (c, f) = t;
Console.WriteLine($"{c}°C = {f}°F"); // 100°C = 212°FTeile der Dekonstruktion ignorieren
Verwenden Sie Discards (_), um unerwünschte Teile einer Dekonstruktion zu ignorieren – ähnlich wie bei Tupel-Discards.
public record Order(int Id, string Customer, decimal Total, DateTime Date);
var order = new Order(42, "Alice", 99.99m, DateTime.UtcNow);
// Only want Id and Total
var (id, _, total, _) = order;
Console.WriteLine($"Order {id}: ${total}");
// In switch: ignore some fields
string Classify(Order o) => o switch
{
(_, _, > 1000, _) => "High value",
(_, _, > 100, _) => "Medium value",
_ => "Low value"
};Eigenschaftsmuster und positionale Muster
Records unterstützen sowohl positionale Muster (nach Position) als auch Eigenschaftsmuster (nach Namen). Eigenschaftsmuster sind bei Records mit vielen Eigenschaften besser lesbar.
public record Order(int Id, string Status, decimal Total);
// Positional pattern:
string DescribePos(Order o) => o switch
{
(_, "Shipped", > 100) => "High-value shipped",
_ => "Other"
};
// Property pattern (more readable):
string DescribeProp(Order o) => o switch
{
{ Status: "Shipped", Total: > 100 } => "High-value shipped",
{ Status: "Cancelled" } => "Cancelled",
_ => "Other"
};Praxisbeispiel: Result-Type-Muster
Ein Result-Type nach dem Muster einer discriminated union, das Records und Dekonstruktion verwendet – ein funktionaler Ansatz zur Fehlerbehandlung.
public abstract record Result<T>;
public record Success<T>(T Value) : Result<T>;
public record Failure<T>(string Error) : Result<T>;
Result<Order> PlaceOrder(CreateOrderRequest req)
{
if (req.Quantity <= 0)
return new Failure<Order>("Quantity must be positive");
var order = CreateOrder(req);
return new Success<Order>(order);
}
// Consuming:
var result = PlaceOrder(request);
switch (result)
{
case Success<Order>(var order):
return Results.Created($"/orders/{order.Id}", order);
case Failure<Order>(var error):
return Results.BadRequest(error);
}Schnelltest
Was bewirkt die Verwendung eines Discards (_) in einem Dekonstruktionsausdruck?
Zusammenfassung: Wertgleichheit und Dekonstruktion
Wichtigste Erkenntnisse:
- Automatisch generierte Gleichheit vergleicht alle Eigenschaften strukturell und rekursiv
- Überschreiben Sie Equals/GetHashCode bei Records für eine benutzerdefinierte Identitätslogik
- Records funktionieren korrekt als Elemente eines HashSet und als Schlüssel von Dictionaries
- Positions-Records generieren Deconstruct automatisch — verwenden Sie var (a, b) = record
- Discards (_) ignorieren unerwünschte Positionswerte bei der Dekomposition
- Eigenschaftsmuster ({Status: "X"}) sind bei komplexen Records besser lesbar als Positionsmuster
Häufig gestellte Fragen
Ist die Lektion „Wertgleichheit und Dekonstruktion“ kostenlos?
Ja — der vollständige Text von „Wertgleichheit und Dekonstruktion“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des C# Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der C# Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Wertgleichheit und Dekonstruktion“?
Verstehen Sie die strukturelle Gleichheit von Records, überschreiben Sie Equals/GetHashCode und verwenden Sie Dekonstruktionsmuster. Du übst C# Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um C# Academy zu starten?
Keine Vorkenntnisse erforderlich. C# Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.
Wie lange dauert die Lektion „Wertgleichheit und Dekonstruktion“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser C# Academy-Lektion Code schreiben und ausführen?
Ja. Jede C# Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Record-Typen: Grundlagen und Syntax
- Unveränderlichkeit mit init und with
- Wertgleichheit und Dekonstruktion
- Records im Domain-Driven Design