0Pricing
C# Academy · Lezione

Tipi record: basi e sintassi

Dichiari record class e record struct, comprenda la sintassi posizionale e confronti record e classi.

Tipi record: basi e sintassi è una lezione C# Academy gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C# Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C# Academy include 4 lezioni in totale.

Che cosa sono i tipi record?

I record (introdotti in C# 9) sono tipi riferimento progettati per dati immutabili con semantica di valore. Generano automaticamente l'uguaglianza basata sui valori delle proprietà, un ToString() leggibile e supportano la modifica non distruttiva tramite le espressioni with.

Sintassi dei record posizionali

La sintassi posizionale è la forma più concisa. Proprietà, costruttore, destrutturazione e uguaglianza vengono generati tutti da una singola riga.

// 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 }"

Record e classi

I record e le classi differiscono principalmente per l'uguaglianza predefinita e per il loro scopo. I record usano l'uguaglianza strutturale (basata sui valori), mentre le classi usano l'uguaglianza per riferimento (basata sull'identità).

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

Record struct

C# 10 introduce record struct, ovvero record di tipo valore. Presentano le stesse funzionalità di uguaglianza e ToString dei record class, ma vengono allocati nello stack come le struct.

// 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);

Dichiarazione standard di un record con corpo

I record possono avere un corpo completo, con proprietà calcolate, metodi e validazione nel costruttore, mantenendo al contempo l'uguaglianza e il ToString automatici.

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() };
}

Ereditarietà con i record

I record supportano l'ereditarietà. Un record derivato aggiunge altre proprietà e partecipa alle stesse regole di uguaglianza: due record sono uguali solo se il tipo e tutti i valori corrispondono.

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

Proprietà non posizionali dei record

I record non sono limitati ai parametri posizionali. È possibile combinare proprietà posizionali e manuali e utilizzare inizializzatori di proprietà per impostare i valori predefiniti.

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
};

Destrutturazione

I record posizionali generano automaticamente un metodo Deconstruct, che consente di destrutturarli nelle assegnazioni e nel pattern matching.

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})"
};

I record come DTO

I record sono eccellenti per i DTO delle richieste e delle risposte API. Sono immutabili e serializzabili, e la loro uguaglianza generata automaticamente semplifica i test.

// 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));
});

Uguaglianza dei record negli unit test

L'uguaglianza per valore rende i record ideali per le asserzioni degli unit test. È possibile confrontare i record attesi ed effettivi con == o Assert.Equal senza comparatori personalizzati.

[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);
}

Verifica rapida

Quale semantica di uguaglianza utilizzano i record C# per impostazione predefinita?

Riepilogo: nozioni di base sui tipi record

Punti chiave:

  • I record sono tipi riferimento con uguaglianza per valore (strutturale) per impostazione predefinita
  • La sintassi posizionale genera costruttore, Deconstruct, uguaglianza e ToString
  • record struct (C# 10) è una variante di tipo valore
  • I record supportano l'ereditarietà: anche il tipo deve corrispondere perché ci sia uguaglianza
  • Sono perfetti per DTO, contratti API e asserzioni degli unit test
  • È possibile aggiungere proprietà calcolate e metodi in un blocco del corpo, insieme ai parametri posizionali

Domande Frequenti

La lezione «Tipi record: basi e sintassi» è gratuita?

Sì — il testo completo di «Tipi record: basi e sintassi» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C# Academy, passa a CoddyKit PRO. Il corso C# Academy include 4 lezioni in totale.

Cosa imparerò in «Tipi record: basi e sintassi»?

Dichiari record class e record struct, comprenda la sintassi posizionale e confronti record e classi. Eserciti C# Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare C# Academy?

Non è richiesta alcuna esperienza precedente. C# Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.

Quanto tempo richiede la lezione «Tipi record: basi e sintassi»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione C# Academy?

Sì. Ogni lezione C# Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Tipi record: basi e sintassi
  2. Immutabilità con init e with
  3. Uguaglianza per valore e destrutturazione
  4. Record nel Domain-Driven Design
← Torna a C# Academy