C# Academy · Lektion

Record-typer: Grundlag og syntaks

Deklarér record-klasser og record-structs, forstå positionssyntaks, og sammenlign records med klasser.

Lektion 1 af 412 trin

Record-typer: Grundlag og syntaks er en gratis C# Academy-lektion på CoddyKit. Dette er lektion 1 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i C# Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. C# Academy-kurset indeholder 4 lektioner i alt.

Hvad er recordtyper?

Recordtyper (introduceret i C# 9) er referencetyper, der er designet til uforanderlige data med værdibaseret semantik. De genererer automatisk lighed baseret på egenskabernes værdier, en letlæselig ToString() og understøtter ikke-destruktiv ændring via with-udtryk.

Positionssyntaks for recordtyper

Positionssyntaksen er den mest kompakte form. Egenskaber, konstruktør, dekomponering og lighed genereres alle ud fra en enkelt linje.

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

Recordtyper kontra klasser

Recordtyper og klasser adskiller sig primært i deres standardlighed og formål. Recordtyper bruger strukturel lighed (værdier), mens klasser bruger referencelighed (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

Recordstrukturer

C# 10 tilføjer record struct — recordtyper af værditype. De har de samme funktioner for lighed og ToString som recordklasser, men allokeres på stacken ligesom strukturer.

// 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 af recordtype med krop

Recordtyper kan have en fuld krop — du kan tilføje beregnede egenskaber, metoder og validering i konstruktøren, samtidig med at den automatiske lighed og ToString bevares.

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

Nedarvning med recordtyper

Recordtyper understøtter nedarvning. En afledt recordtype tilføjer flere egenskaber og følger de samme lighedsregler — to recordtyper er kun ens, hvis deres typer og alle værdier stemmer overens.

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

Ikke-positionelle egenskaber i recordtyper

Recordtyper er ikke begrænset til positionsparametre. Du kan blande positions- og manuelt definerede egenskaber og bruge egenskabsinitialiseringer til standardværdier.

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

Dekomponering

Positionsbaserede recordtyper genererer automatisk en Deconstruct-metode, så de kan dekomponeres i tildelinger og 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})"
};

Recordtyper som DTO'er

Recordtyper er fremragende til DTO'er for API-anmodninger og -svar. De er uforanderlige og serialiserbare, og deres automatisk genererede lighed gør test enklere.

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

Lighed for recordtyper i enhedstest

Værdibaseret lighed gør recordtyper ideelle til påstande i enhedstest. Du kan sammenligne forventede og faktiske recordtyper med == eller Assert.Equal uden brugerdefinerede sammenlignere.

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

Hurtigt tjek

Hvilken lighedssemantik bruger C#-recordtyper som standard?

Opsummering: Grundlæggende om recordtyper

Vigtige pointer:

  • Recordtyper er referencetyper med værdibaseret (strukturel) lighed som standard
  • Positionssyntaks genererer konstruktør, dekomponering, lighed og ToString
  • record struct (C# 10) er en variant af værditype
  • Recordtyper understøtter nedarvning — typen skal også stemme overens for at opnå lighed
  • De er perfekte til DTO'er, API-kontrakter og påstande i enhedstest
  • Tilføj beregnede egenskaber og metoder i en kropsblok sammen med positionsparametre
Gratis at komme i gang

Lær C# med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
93
Lektioner
346

Ofte stillede spørgsmål

Er lektionen “Record-typer: Grundlag og syntaks” gratis?

Ja — hele teksten til “Record-typer: Grundlag og syntaks” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af C# Academy-kurset, skal du opgradere til CoddyKit PRO. C# Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Record-typer: Grundlag og syntaks”?

Deklarér record-klasser og record-structs, forstå positionssyntaks, og sammenlign records med klasser. Du øver dig i C# Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på C# Academy?

Der kræves ingen tidligere erfaring. C# Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 1 af 4.

Hvor lang tid tager lektionen “Record-typer: Grundlag og syntaks”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne C# Academy-lektion?

Ja. Alle C# Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Record-typer: Grundlag og syntaks
  2. Uforanderlighed med init og with
  3. Værdilighed og deconstruction
  4. Records i Domain-Driven Design
← Tilbage til C# Academy