Typy record: podstawy i składnia
Deklaruj klasy record i struktury record, poznaj składnię pozycyjną oraz porównuj rekordy z klasami.
Typy record: podstawy i składnia to bezpłatna lekcja C# Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C# Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C# Academy zawiera 4 lekcji w sumie.
Czym są typy rekordowe
Rekordy (wprowadzone w C# 9) to typy referencyjne zaprojektowane z myślą o niezmiennych danych z semantyką wartości. Automatycznie generują porównywanie na podstawie wartości właściwości, czytelną implementację ToString() oraz obsługują niedestrukcyjną modyfikację za pomocą wyrażeń with.
Składnia rekordów pozycyjnych
Składnia pozycyjna jest najbardziej zwięzłą formą deklaracji. Właściwości, konstruktor, dekonstrukcja i porównywanie są generowane na podstawie jednego wiersza.
// 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 }"Rekordy a klasy
Rekordy i klasy różnią się przede wszystkim domyślnym sposobem porównywania oraz przeznaczeniem. Rekordy używają równości strukturalnej (wartości), natomiast klasy używają równości referencyjnej (tożsamości).
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 referencesStruktury rekordowe
C# 10 wprowadza record struct — rekordy będące typami wartościowymi. Mają te same funkcje porównywania i ToString co klasy rekordowe, ale są alokowane na stosie tak jak struktury.
// 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);Standardowa deklaracja rekordu z ciałem
Rekordy mogą mieć pełne ciało, w którym można dodać właściwości obliczane, metody i walidację w konstruktorze, zachowując jednocześnie automatyczne porównywanie i ToString.
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() };
}Dziedziczenie w rekordach
Rekordy obsługują dziedziczenie. Rekord pochodny może dodawać kolejne właściwości i uczestniczy w tych samych zasadach porównywania — dwa rekordy są równe tylko wtedy, gdy ich typy oraz wszystkie wartości są zgodne.
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 typesWłaściwości rekordów niepozycyjnych
Rekordy nie ograniczają się do parametrów pozycyjnych. Można łączyć parametry pozycyjne z właściwościami deklarowanymi ręcznie oraz używać inicjalizatorów właściwości do definiowania wartości domyślnych.
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
};Dekonstrukcja
Rekordy pozycyjne automatycznie generują metodę Deconstruct, dzięki czemu można je rozpakowywać w przypisaniach i podczas dopasowywania wzorców.
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})"
};Rekordy jako DTO
Rekordy doskonale nadają się do DTO żądań i odpowiedzi API. Są niezmienne i możliwe do serializacji, a automatycznie generowane porównywanie upraszcza testowanie.
// 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));
});Porównywanie rekordów w testach jednostkowych
Równość wartości sprawia, że rekordy doskonale nadają się do asercji w testach jednostkowych. Oczekiwane i rzeczywiste rekordy można porównywać za pomocą == lub Assert.Equal, bez tworzenia niestandardowych obiektów porównujących.
[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);
}Szybkie sprawdzenie
Jaką semantykę równości domyślnie stosują rekordy C#?
Podsumowanie: Podstawy typów rekordowych
Najważniejsze informacje:
- Rekordy są typami referencyjnymi, które domyślnie używają równości wartości (strukturalnej)
- Składnia pozycyjna generuje konstruktor, metodę deconstruct, porównywanie i ToString
record struct(C# 10) to wariant będący typem wartościowym- Rekordy obsługują dziedziczenie — aby rekordy były równe, ich typy również muszą być zgodne
- Doskonale nadają się do DTO, kontraktów API i asercji w testach jednostkowych
- W bloku ciała można dodawać właściwości obliczane i metody obok parametrów pozycyjnych
Często zadawane pytania
Czy lekcja „Typy record: podstawy i składnia” jest bezpłatna?
Tak — pełny tekst „Typy record: podstawy i składnia” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C# Academy, przejdź na CoddyKit PRO. Kurs C# Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Typy record: podstawy i składnia”?
Deklaruj klasy record i struktury record, poznaj składnię pozycyjną oraz porównuj rekordy z klasami. Ćwiczysz C# Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć C# Academy?
Nie wymagamy żadnego doświadczenia. C# Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.
Ile czasu zajmuje lekcja „Typy record: podstawy i składnia”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji C# Academy?
Tak. Każda lekcja C# Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Typy record: podstawy i składnia
- Niemutowalność z init i with
- Równość wartości i dekonstrukcja
- Rekordy w projektowaniu sterowanym domeną