Inleiding tot recordtypen in C#

Een record in C# is een klasse of struct die speciale syntaxis en gedrag biedt voor het werken met gegevensmodellen. Met de record wijzigingsfunctie wordt de compiler geïnstrueerd om leden te synthetiseren die nuttig zijn voor typen waarvan de primaire rol gegevens opslaat. Deze leden omvatten een overbelasting van ToString() en leden die waarde-gelijkheid ondersteunen.

Wanneer records worden gebruikt

Overweeg het gebruik van een record in plaats van een klasse of struct in de volgende scenario's:

  • U wilt een gegevensmodel definiëren dat afhankelijk is van gelijkheid van waarden.
  • U wilt een type definiëren waarvoor objecten onveranderbaar zijn.

Gelijkheid van waarde

Voor records betekent gelijkheid van waarden dat twee variabelen van een recordtype gelijk zijn als de typen overeenkomen en alle eigenschaps- en veldwaarden overeenkomen. Voor andere referentietypen, zoals klassen, betekent gelijkheid verwijzing naar gelijkheid. Dat wil gezegd: twee variabelen van een klassetype zijn gelijk als ze naar hetzelfde object verwijzen. Methoden en operators die gelijkheid van twee recordexemplaren bepalen, maken gebruik van gelijkheid van waarden.

Niet alle gegevensmodellen werken goed met gelijkheid van waarden. Entity Framework Core is bijvoorbeeld afhankelijk van gelijkheid van verwijzingen om ervoor te zorgen dat er slechts één exemplaar van een entiteitstype wordt gebruikt voor wat conceptueel één entiteit is. Daarom zijn recordtypen niet geschikt voor gebruik als entiteitstypen in Entity Framework Core.

Onveranderbaarheid

Een onveranderbaar type is een type dat voorkomt dat u eigenschaps- of veldwaarden van een object wijzigt nadat het is geïnstantieerd. Onveranderbaarheid kan handig zijn wanneer u een type nodig hebt om thread-veilig te zijn of als u afhankelijk bent van een hash-code die hetzelfde blijft in een hash-tabel. Records bieden beknopte syntaxis voor het maken en werken met onveranderbare typen.

Onveranderbaarheid is niet geschikt voor alle gegevensscenario's. Entity Framework Core biedt bijvoorbeeld geen ondersteuning voor het bijwerken met onveranderbare entiteitstypen.

Hoe records verschillen van klassen en structs

Dezelfde syntaxis waarmee klassen of structs worden gede declareerd en geïnstitueerd, kunnen worden gebruikt met records. Vervang het class trefwoord door het recordof gebruik record struct in plaats van struct. Dezelfde syntaxis voor het uitdrukken van overnamerelaties wordt ook ondersteund door recordklassen. Records verschillen van klassen op de volgende manieren:

  • U kunt positionele parameters in een primaire constructor gebruiken om een type te maken en te instantiëren met onveranderbare eigenschappen.
  • Dezelfde methoden en operators die verwijzen naar gelijkheid of ongelijkheid in klassen (zoals Object.Equals(Object) en ==), geven waarde-gelijkheid of ongelijkheid in records aan.
  • U kunt een with expressie gebruiken om een kopie van een onveranderbaar object te maken met nieuwe waarden in geselecteerde eigenschappen.
  • Met de methode van ToString een record maakt u een opgemaakte tekenreeks met de typenaam van een object en de namen en waarden van alle openbare eigenschappen.
  • Een record kan overnemen van een andere record. Een record kan niet worden overgenomen van een klasse en een klasse kan niet overnemen van een record.

Record-structs verschillen van structs in dat de compiler de methoden voor gelijkheid samenlegt, en ToString. De compiler synthetiseert een Deconstruct methode voor positionele record-structs.

De compiler synthetiseert een openbare init-only eigenschap voor elke primaire constructorparameter in een record class. In een record struct, de compiler synthetiseert een openbare eigenschap voor lezen/schrijven. De compiler maakt geen eigenschappen voor primaire constructorparameters in class en struct typen die geen wijzigingsfunctie bevatten record .

Voorbeelden

In het volgende voorbeeld wordt een openbare record gedefinieerd die gebruikmaakt van positionele parameters om een record te declareren en te instantiëren. Vervolgens worden de typenaam en eigenschapswaarden afgedrukt:


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

}

In het volgende voorbeeld ziet u gelijkheid van waarden in records:

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

In het volgende voorbeeld ziet u hoe u een with expressie gebruikt om een onveranderbaar object te kopiëren en een van de eigenschappen te wijzigen:

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

Zie Records (C#-verwijzing) voor meer informatie.

C#-taalspecificatie

Zie de C#-taalspecificatie voor meer informatie. De taalspecificatie is de definitieve bron voor de C#-syntaxis en het gebruik.