C# Academy · Lektion

Record-typer: grunder och syntax

Deklarera record-klasser och record-struktar, förstå positionssyntax och jämför records med klasser.

Lektion 1 av 412 steg

Record-typer: grunder och syntax är en gratis lektion i C# Academy på CoddyKit. Detta är lektion 1 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för C# Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i C# Academy innehåller totalt 4 lektioner.

Vad är record-typer?

Records (introducerades i C# 9) är referenstyper utformade för oföränderlig data med värdesemantik. De genererar automatiskt likhet baserad på egenskapsvärden, en lättläst ToString() och stöd för icke-destruktiv förändring via with-uttryck.

Syntax för positionella records

Den positionella syntaxen är den mest kompakta formen. Egenskaper, konstruktor, destrukturering och likhet genereras alla från en enda rad.

// 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 och klasser

Records och klasser skiljer sig främst åt när det gäller standardmässig likhet och avsikt. Records använder strukturell likhet (värden), medan klasser använder referenslikhet (identitet).

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 structs

C# 10 introducerar record struct – records som är värdetyper. De har samma funktioner för likhet och ToString som record-klasser, men allokeras på stacken likt structar.

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

Standarddeklaration av record med kropp

Records kan ha en fullständig kropp där du lägger till beräknade egenskaper, metoder och validering i konstruktorn, samtidigt som den automatiska likheten och ToString behålls.

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

Arv med records

Records stöder arv. En härledd record-typ lägger till fler egenskaper och följer samma likhetsregler – två records är lika endast om deras typer och alla värden överensstämmer.

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

Icke-positionella record-egenskaper

Records är inte begränsade till positionella parametrar. Du kan blanda positionella och manuella egenskaper och använda egenskapsinitierare för standardvärden.

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

Destrukturering

Positionella records genererar automatiskt en Deconstruct-metod, vilket gör det möjligt att destrukturera dem i tilldelningar och mönstermatchning.

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 som DTO:er

Records passar utmärkt för DTO:er för API-förfrågningar och API-svar. De är oföränderliga och serialiserbara, och deras automatiskt genererade likhet förenklar testning.

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

Record-likhet i enhetstester

Värdelikhet gör records idealiska för assertioner i enhetstester. Du kan jämföra förväntade och faktiska records med == eller Assert.Equal utan egna jämförare.

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

Snabbkontroll

Vilken likhetssemantik använder C#-records som standard?

Sammanfattning: Grunderna i record-typer

Viktigaste punkterna:

  • Records är referenstyper med värdebaserad (strukturell) likhet som standard
  • Positionell syntax genererar konstruktor, deconstruct, likhet och ToString
  • record struct (C# 10) är en variant som är en värdetyp
  • Records stöder arv – typen måste också matcha för att likheten ska gälla
  • Perfekta för DTO:er, API-avtal och assertioner i enhetstester
  • Lägg till beräknade egenskaper och metoder i ett kroppblock tillsammans med positionella parametrar
Gratis att börja

Lär dig C# med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
93
Lektioner
346

Vanliga frågor

Är lektionen ”Record-typer: grunder och syntax” gratis?

Ja – hela texten till ”Record-typer: grunder och syntax” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i C# Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i C# Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”Record-typer: grunder och syntax”?

Deklarera record-klasser och record-struktar, förstå positionssyntax och jämför records med klasser. Ni övar på C# Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig C# Academy?

Du behöver inga förkunskaper. Utbildningen i C# Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 1 av 4.

Hur lång tid tar lektionen ”Record-typer: grunder och syntax”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här C# Academy-lektionen?

Ja. Varje C# Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Record-typer: grunder och syntax
  2. Oföränderlighet med init och with
  3. Värdelikhet och dekomponering
  4. Records i domändriven design
← Tillbaka till C# Academy