Wprowadzenie do typów rekordów w języku C#

Rekord w języku C# to klasa lub struktura, która zapewnia specjalną składnię i zachowanie do pracy z modelami danych. record Modyfikator instruuje kompilator, aby syntetyzował elementy członkowskie, które są przydatne w przypadku typów, których rola podstawowa przechowuje dane. Te elementy członkowskie obejmują przeciążenie elementów ToString() członkowskich, które obsługują równość wartości.

Kiedy należy używać rekordów

Rozważ użycie rekordu zamiast klasy lub struktury w następujących scenariuszach:

  • Chcesz zdefiniować model danych, który zależy od równości wartości.
  • Chcesz zdefiniować typ, dla którego obiekty są niezmienne.

Równość wartości

W przypadku rekordów równość wartości oznacza, że dwie zmienne typu rekordu są równe, jeśli typy są zgodne, a wszystkie wartości właściwości i pól są zgodne. W przypadku innych typów odwołań, takich jak klasy, równość oznacza równość odwołania. Oznacza to, że dwie zmienne typu klasy są równe, jeśli odwołują się do tego samego obiektu. Metody i operatory, które określają równość dwóch wystąpień rekordów, używają równości wartości.

Nie wszystkie modele danych działają dobrze z równością wartości. Na przykład platforma Entity Framework Core zależy od równości referencyjnej, aby upewnić się, że używa tylko jednego wystąpienia typu jednostki dla tego, co jest koncepcyjnie jedną jednostką. Z tego powodu typy rekordów nie są odpowiednie do użycia jako typy jednostek w programie Entity Framework Core.

Niezmienność

Niezmienny typ jest taki, który uniemożliwia zmianę wszelkich wartości właściwości lub pól obiektu po jego utworzeniu. Niezmienność może być przydatna, gdy potrzebujesz typu bezpiecznego wątkowo lub zależysz od kodu skrótu, który pozostaje taki sam w tabeli skrótu. Rekordy zapewniają zwięzłą składnię tworzenia i pracy z niezmienialnymi typami.

Niezmienność nie jest odpowiednia dla wszystkich scenariuszy danych. Na przykład program Entity Framework Core nie obsługuje aktualizacji przy użyciu niezmiennych typów jednostek.

Czym różnią się rekordy od klas i struktur

Ta sama składnia, która deklaruje i tworzy wystąpienia klas lub struktur, może być używana z rekordami. Wystarczy zastąpić słowo class kluczowe ciągiem record, lub zamiast record structstruct. Podobnie ta sama składnia wyrażania relacji dziedziczenia jest obsługiwana przez klasy rekordów. Rekordy różnią się od klas w następujący sposób:

  • Można użyć parametrów pozycyjnych w konstruktorze podstawowym, aby utworzyć i utworzyć wystąpienie typu z niezmiennymi właściwościami.
  • Te same metody i operatory, które wskazują równość odwołania lub nierówności w klasach (takich jak Object.Equals(Object) i ), wskazują równość wartości lub nierówności==w rekordach.
  • Możesz użyć with wyrażenia , aby utworzyć kopię niezmiennego obiektu z nowymi wartościami we wybranych właściwościach.
  • Metoda rekordu ToString tworzy sformatowany ciąg, który pokazuje nazwę typu obiektu oraz nazwy i wartości wszystkich jego właściwości publicznych.
  • Rekord może dziedziczyć z innego rekordu. Rekord nie może dziedziczyć z klasy, a klasa nie może dziedziczyć z rekordu.

Struktury rekordów różnią się od struktur, w których kompilator syntetyzuje metody równości i ToString. Kompilator syntetyzuje metodę Deconstruct dla struktur rekordów pozycyjnych.

Kompilator syntetyzuje publiczną właściwość tylko do inicjowania dla każdego podstawowego parametru konstruktora w obiekcie record class. W programie record structkompilator syntetyzuje publiczną właściwość read-write. Kompilator nie tworzy właściwości podstawowych parametrów konstruktora w class elementach i struct typach, które nie zawierają record modyfikatora.

Przykłady

W poniższym przykładzie zdefiniowano publiczny rekord, który używa parametrów pozycyjnych do deklarowania i tworzenia wystąpienia rekordu. Następnie wyświetla nazwę typu i wartości właściwości:


public record Person(string FirstName, string LastName);

public static class Program
{
    public static void Main()
    {
        Person person = new("Nancy", "Davolio");
        Console.WriteLine(person);
        // output: Person { FirstName = Nancy, LastName = Davolio }
    }

}

W poniższym przykładzie pokazano równość wartości w rekordach:

public record Person(string FirstName, string LastName, string[] PhoneNumbers);
public static class Program
{
    public static void Main()
    {
        var phoneNumbers = new string[2];
        Person person1 = new("Nancy", "Davolio", phoneNumbers);
        Person person2 = new("Nancy", "Davolio", phoneNumbers);
        Console.WriteLine(person1 == person2); // output: True

        person1.PhoneNumbers[0] = "555-1234";
        Console.WriteLine(person1 == person2); // output: True

        Console.WriteLine(ReferenceEquals(person1, person2)); // output: False
    }
}

W poniższym przykładzie pokazano użycie with wyrażenia w celu skopiowania niezmiennego obiektu i zmiany jednej z właściwości:

public record Person(string FirstName, string LastName)
{
    public required string[] PhoneNumbers { get; init; }
}

public class Program
{
    public static void Main()
    {
        Person person1 = new("Nancy", "Davolio") { PhoneNumbers = new string[1] };
        Console.WriteLine(person1);
        // output: Person { FirstName = Nancy, LastName = Davolio, PhoneNumbers = System.String[] }

        Person person2 = person1 with { FirstName = "John" };
        Console.WriteLine(person2);
        // output: Person { FirstName = John, LastName = Davolio, PhoneNumbers = System.String[] }
        Console.WriteLine(person1 == person2); // output: False

        person2 = person1 with { PhoneNumbers = new string[1] };
        Console.WriteLine(person2);
        // output: Person { FirstName = Nancy, LastName = Davolio, PhoneNumbers = System.String[] }
        Console.WriteLine(person1 == person2); // output: False

        person2 = person1 with { };
        Console.WriteLine(person1 == person2); // output: True
    }
}

Aby uzyskać więcej informacji, zobacz Rekordy (odwołanie w C#).

Specyfikacja języka C#

Aby uzyskać więcej informacji, zobacz Specyfikacja języka C#. Specyfikacja języka jest ostatecznym źródłem informacji o składni i użyciu języka C#.