0Pricing
C# Academy · Lección

Tipos record: fundamentos y sintaxis

Declare clases record y structs record, comprenda la sintaxis posicional y compare records con clases.

Tipos record: fundamentos y sintaxis es una lección gratuita de C# Academy en CoddyKit. Esta es la lección 1 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.

¿Qué son los tipos record?

Los records (introducidos en C# 9) son tipos de referencia diseñados para datos inmutables con semántica de valor. Generan automáticamente igualdad basada en los valores de las propiedades, un ToString() legible y permiten realizar mutaciones no destructivas mediante expresiones with.

Sintaxis de record posicional

La sintaxis posicional es la forma más concisa. Las propiedades, el constructor, la deconstrucción y la igualdad se generan a partir de una sola línea.

// All in one line:
public record Point(double X, double Y);
public record Person(string FirstName, string LastName, int Age);

// Generated automatically:
// - Primary constructor: new Point(1.0, 2.0)
// - Deconstruct: var (x, y) = point;
// - Equality: p1 == p2 compares X and Y values
// - ToString: "Point { X = 1, Y = 2 }"

Records frente a clases

Los records y las clases se diferencian principalmente en su igualdad predeterminada y en su propósito. Los records usan igualdad estructural (valores), mientras que las clases usan igualdad por referencia (identidad).

var p1 = new Point(1, 2);
var p2 = new Point(1, 2);
var p3 = p1;

// Record: structural equality
Console.WriteLine(p1 == p2); // True — same values
Console.WriteLine(p1 == p3); // True — same values

// Compare with a class:
var c1 = new PointClass(1, 2);
var c2 = new PointClass(1, 2);
Console.WriteLine(c1 == c2); // False — different references

Records de tipo struct

C# 10 añade record struct, es decir, records de tipo valor. Tienen las mismas características de igualdad y ToString que las clases record, pero se asignan en la pila como los structs.

// Record struct: value type, stack-allocated
public record struct Color(byte R, byte G, byte B);

var red   = new Color(255, 0, 0);
var red2  = new Color(255, 0, 0);
Console.WriteLine(red == red2); // True — value equality

// Readonly record struct: fully immutable
public readonly record struct Coord(double Lat, double Lng);

Declaración estándar de record con cuerpo

Los records pueden tener un cuerpo completo: permiten añadir propiedades calculadas, métodos y validación en el constructor, conservando la igualdad y el ToString automáticos.

public record Person(string FirstName, string LastName)
{
    // Computed property
    public string FullName => $"{FirstName} {LastName}";

    // Validation in constructor
    public Person : this(FirstName, LastName)
    {
        if (string.IsNullOrWhiteSpace(FirstName))
            throw new ArgumentException("FirstName required");
    }

    // Method
    public Person WithUpperCase() =>
        this with { FirstName = FirstName.ToUpper(), LastName = LastName.ToUpper() };
}

Herencia con records

Los records admiten herencia. Un record derivado añade más propiedades y participa en las mismas reglas de igualdad: dos records solo son iguales si sus tipos y todos sus valores coinciden.

public record Shape(string Color);
public record Circle(string Color, double Radius) : Shape(Color);
public record Rectangle(string Color, double Width, double Height) : Shape(Color);

var c1 = new Circle("red", 5.0);
var c2 = new Circle("red", 5.0);
var r1 = new Rectangle("red", 5.0, 3.0);

Console.WriteLine(c1 == c2); // True
Console.WriteLine(c1 == r1); // False — different types

Propiedades no posicionales de los records

Los records no se limitan a los parámetros posicionales. Puede combinar propiedades posicionales y manuales, y usar inicializadores de propiedades para establecer valores predeterminados.

public record Order
{
    public int Id { get; init; }
    public string CustomerName { get; init; } = "";
    public List<OrderLine> Lines { get; init; } = new();
    public DateTime CreatedAt { get; init; } = DateTime.UtcNow;
    public OrderStatus Status { get; init; } = OrderStatus.Pending;
}

// Initialization:
var order = new Order
{
    Id = 42,
    CustomerName = "Alice"
    // Other props use defaults
};

Deconstrucción

Los records posicionales generan automáticamente un método Deconstruct, lo que permite descomponerlos en asignaciones y en coincidencias de patrones.

public record Point(double X, double Y);

var p = new Point(3.0, 4.0);

// Deconstruction
var (x, y) = p;
Console.WriteLine($"x={x}, y={y}");

// In switch:
string Describe(Point pt) => pt switch
{
    (0, 0) => "Origin",
    (double x, 0) => $"On X-axis at {x}",
    (0, double y) => $"On Y-axis at {y}",
    var (px, py)  => $"Point ({px}, {py})"
};

Records como DTO

Los records son excelentes para los DTO de solicitudes y respuestas de API. Son inmutables y serializables, y su igualdad generada automáticamente simplifica las pruebas.

// API request/response records
public record CreateProductRequest(
    string Name,
    decimal Price,
    int Stock);

public record ProductResponse(
    int Id,
    string Name,
    decimal Price,
    int Stock,
    DateTime CreatedAt);

// In controller:
app.MapPost("/products", (CreateProductRequest req, ProductService svc) =>
{
    var product = svc.Create(req.Name, req.Price, req.Stock);
    return Results.Created($"/products/{product.Id}",
        new ProductResponse(product.Id, product.Name,
                            product.Price, product.Stock,
                            product.CreatedAt));
});

Igualdad de records en pruebas unitarias

La igualdad por valor hace que los records sean ideales para las aserciones de pruebas unitarias. Puede comparar los records esperado y real con == o Assert.Equal sin comparadores personalizados.

[Fact]
public async Task CreateOrder_ReturnsCorrectResponse()
{
    var response = await _client.PostAsJsonAsync("/orders",
        new CreateOrderRequest(CustomerId: 1, ProductId: 5, Quantity: 2));

    var order = await response.Content.ReadFromJsonAsync<OrderResponse>();

    // Simple equality check — no custom IEqualityComparer needed!
    Assert.Equal(
        new OrderResponse(Id: order!.Id, Status: "Pending", Total: 99.98m),
        order);
}

Comprobación rápida

¿Qué semántica de igualdad usan los records de C# de forma predeterminada?

Resumen: conceptos básicos de los tipos record

Conceptos clave:

  • Los records son tipos de referencia con igualdad por valor (estructural) de forma predeterminada
  • La sintaxis posicional genera el constructor, Deconstruct, la igualdad y ToString
  • record struct (C# 10) es una variante de tipo valor
  • Los records admiten herencia; el tipo también debe coincidir para que exista igualdad
  • Son ideales para DTO, contratos de API y aserciones de pruebas unitarias
  • Añada propiedades calculadas y métodos en un bloque de cuerpo junto a los parámetros posicionales

Preguntas frecuentes

¿La lección «Tipos record: fundamentos y sintaxis» es gratis?

Sí — el texto completo de «Tipos record: fundamentos y sintaxis» 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 «Tipos record: fundamentos y sintaxis»?

Declare clases record y structs record, comprenda la sintaxis posicional y compare records con clases. 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 1 de 4.

¿Cuánto tiempo toma la lección «Tipos record: fundamentos y sintaxis»?

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

  1. Tipos record: fundamentos y sintaxis
  2. Inmutabilidad con init y with
  3. Igualdad de valores y deconstrucción
  4. Records en el diseño guiado por el dominio
← Volver a C# Academy