Igualdad de valores y deconstrucción
Comprenda la igualdad estructural de los records, sobrescriba Equals/GetHashCode y use patrones de deconstrucción.
Igualdad de valores y deconstrucción es una lección gratuita de C# Academy en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de C# Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de C# Academy incluye 4 lecciones en total.
Análisis detallado de la igualdad de records
Los records generan automáticamente Equals, GetHashCode y los operadores ==/!=, que comparan estructuralmente todas las propiedades. Comprender este funcionamiento le ayuda a usar records correctamente y a sobrescribirlo cuando sea necesario.
Cómo funciona la igualdad generada automáticamente
El compilador genera código que compara cada propiedad mediante EqualityComparer<T>.Default. En las propiedades de tipo de referencia, este usa su propio Equals, no la igualdad por referencia.
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 ✓Sobrescritura de la igualdad generada
Puede sobrescribir Equals y GetHashCode en un record cuando necesite una lógica de igualdad personalizada, por ejemplo, para comparar solo un subconjunto de propiedades.
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 en colecciones
Como los records implementan IEquatable<T> con igualdad estructural, funcionan correctamente como claves de diccionario, en HashSets y con Distinct y GroupBy de LINQ.
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")); // trueDeconstrucción: conceptos básicos
Los records posicionales generan automáticamente un método Deconstruct con parámetros out para cada propiedad posicional. Esto permite desempaquetarlos como tuplas.
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}");Deconstrucción en la coincidencia de patrones
La deconstrucción de records en expresiones switch permite realizar coincidencias de patrones posicionales avanzadas.
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 3Métodos Deconstruct personalizados
Los records no posicionales (y cualquier clase) pueden añadir manualmente un método Deconstruct. Los métodos de extensión también pueden añadir deconstrucción a tipos existentes.
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°FIgnorar partes de una deconstrucción
Use descartes (_) para ignorar las partes no deseadas de una deconstrucción, de forma similar a los descartes de tuplas.
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"
};Patrones de propiedades frente a patrones posicionales
Los records admiten tanto patrones posicionales (por posición) como patrones de propiedades (por nombre). Los patrones de propiedades son más legibles en records con muchas propiedades.
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"
};Caso real: patrón de tipo Result
Un tipo de resultado al estilo de una unión discriminada que usa records y deconstrucción: un enfoque funcional para gestionar errores.
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);
}Comprobación rápida
¿Qué efecto tiene usar un descarte (_) en una expresión de deconstrucción?
Resumen: igualdad por valor y deconstrucción
Conclusiones clave:
- La igualdad generada automáticamente compara todas las propiedades de forma estructural y recursiva
- Sobrescriba Equals/GetHashCode en los registros para implementar una lógica de identidad personalizada
- Los registros funcionan correctamente como elementos de HashSet y claves de diccionario
- Los registros posicionales generan automáticamente Deconstruct: use var (a, b) = record
- Los descartes (_) ignoran los valores posicionales que no necesita durante la deconstrucción
- Los patrones de propiedades ({Status: "X"}) son más legibles que los posicionales para registros complejos
Preguntas frecuentes
¿La lección «Igualdad de valores y deconstrucción» es gratis?
Sí — el texto completo de «Igualdad de valores y deconstrucción» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de C# Academy, actualiza a CoddyKit PRO. El curso de C# Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Igualdad de valores y deconstrucción»?
Comprenda la igualdad estructural de los records, sobrescriba Equals/GetHashCode y use patrones de deconstrucción. Practicas C# Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar C# Academy?
No se requiere experiencia previa. C# Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.
¿Cuánto tiempo toma la lección «Igualdad de valores y deconstrucción»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de C# Academy?
Sí. Cada lección de C# Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Tipos record: fundamentos y sintaxis
- Inmutabilidad con init y with
- Igualdad de valores y deconstrucción
- Records en el diseño guiado por el dominio