Desde C# 9, el lenguaje introdujo una nueva palabra clave: record. A simple vista parece una forma alternativa de declarar clases, pero su objetivo es mucho más específico: modelar datos inmutables que se comparan por valor.
Un record es un tipo de referencia que, a diferencia de las clases tradicionales, se compara por valor y está orientado a la inmutabilidad.
public record Person(string Name, int Age);
var p1 = new Person("Ada", 30);
var p2 = new Person("Ada", 30);
Console.WriteLine(p1 == p2); // True
Con clases normales (class), esta comparación daría false, porque se comparan las referencias.
Usá record cuando:
- Te interesa la comparación por valor: Por ejemplo, para representar coordenadas, dinero, personas, productos, etc.
- No necesitás mutabilidad. Los record son inmutables por defecto (aunque podés crear record class mutables, no es lo ideal).
- Estás trabajando con código funcional o DDD. Es perfecto para modelar objetos de valor (value objects).
- Querés usar with para copiar fácilmente con cambios:
var p3 = p1 with { Age = 31 };
¿Cuándo no usar record?
- Cuando necesitás una identidad mutable (por ejemplo, una entidad con un Id que cambia de estado).
- Cuando estás trabajando con frameworks como EF Core que esperan clases tradicionales para el mapeo.
- Cuando necesitás herencia compleja (los record funcionan bien, pero pueden agregar confusión si no se usan con cuidado).
Desde C# 10, también existe record struct: un tipo por valor que se comporta como record, pero como struct.
public readonly record struct Coordinates(int X, int Y);
Ideal para representar datos livianos inmutables, como vectores o puntos.
Si estás modelando datos que no cambian, donde la igualdad semántica importa más que la identidad, y querés un código limpio, expresivo y seguro, record es la herramienta perfecta.