Partager via


Introduction aux types d’enregistrements en C#

Un enregistrement en C# est une classe ou un struct qui fournit une syntaxe et un comportement spéciaux pour l’utilisation de modèles de données. Le modificateur record indique au compilateur de synthétiser des membres utiles pour les types dont le rôle principal stocke des données. Ces membres comprennent une surcharge de ToString() et des membres qui prennent en charge l'égalité des valeurs.

Quand utiliser des enregistrements

Envisagez d’utiliser un enregistrement à la place d’une classe ou d’un struct dans les scénarios suivants :

  • Vous souhaitez définir un modèle de données qui dépend de égalité des valeurs.
  • Vous souhaitez définir un type pour lequel les objets sont immuables.

Égalité des valeurs

Pour les enregistrements, l’égalité des valeurs signifie que deux variables d’un type d’enregistrement sont égales si les types correspondent et que toutes les valeurs de propriété et de champ sont égales. Pour les types de référence tels que les classes, l'égalité signifie par défaut égalité de référence, sauf si l'égalité de valeur a été implémentée. Autrement dit, deux variables d’un type de classe sont égales si elles font référence au même objet. Les méthodes et les opérateurs qui déterminent l’égalité de deux instances d’enregistrement utilisent l’égalité des valeurs.

Tous les modèles de données ne fonctionnent pas correctement avec l’égalité des valeurs. Par exemple, Entity Framework Core dépend de l’égalité de référence pour s’assurer qu’elle utilise une seule instance d’un type d’entité pour ce qui est conceptuellement une seule entité. Pour cette raison, les types d’enregistrements ne sont pas appropriés pour une utilisation en tant que types d’entités dans Entity Framework Core.

Immuabilité

Un type immuable est un type qui vous empêche de modifier toutes les valeurs de propriété ou de champ d’un objet après son instanciation. L’immuabilité peut être utile lorsque vous avez besoin d’un type pour être thread-safe ou que vous dépendez d’un code de hachage restant le même dans une table de hachage. Les enregistrements fournissent une syntaxe concise pour la création et l’utilisation de types immuables.

L’immuabilité n’est pas appropriée pour tous les scénarios de données. Entity Framework Core, par exemple, ne prend pas en charge la mise à jour avec des types d’entités immuables.

Différences entre les enregistrements et les classes et les structs

La même syntaxe qui permet à de déclarer et à d'instancier des classes ou des structs peut être utilisée avec des enregistrements. Remplacez simplement le mot clé class par le record, ou utilisez record struct au lieu de struct. De même, la syntaxe utilisée pour exprimer les relations d’héritage est prise en charge par les classes d’enregistrement. Les enregistrements diffèrent des classes de la manière suivante :

  • Vous pouvez utiliser paramètres positionnels dans un constructeur principal pour créer et instancier un type avec des propriétés immuables.
  • Les mêmes méthodes et opérateurs qui indiquent l’égalité de référence ou l’inégalité dans les classes (telles que Object.Equals(Object) et ==), indiquent égalité de valeur ou inégalité dans les enregistrements.
  • Vous pouvez utiliser une expression with pour créer une copie d’un objet immuable avec de nouvelles valeurs dans les propriétés sélectionnées.
  • La méthode ToString d’un enregistrement crée une chaîne mise en forme qui affiche le nom de type d’un objet et les noms et valeurs de toutes ses propriétés publiques.
  • Un enregistrement peut hériter d’un autre enregistrement. Un enregistrement ne peut pas hériter d’une classe et une classe ne peut pas hériter d’un enregistrement.

Les structs d’enregistrement diffèrent des structs : le compilateur synthétise les méthodes d’égalité et ToString. Le compilateur synthétise une méthode nommée Deconstruct pour les structs de record positionnel.

Le compilateur synthétise une propriété publique init-only pour chaque paramètre de constructeur primaire dans un fichier record class. Dans un record struct, le compilateur synthétise une propriété publique en lecture-écriture. Le compilateur ne crée pas de propriétés pour les paramètres de constructeur principal dans class et les types struct qui n’incluent pas record modificateur.

Exemples

L’exemple suivant définit un enregistrement public qui utilise des paramètres positionnels pour déclarer et instancier un enregistrement. Il imprime ensuite le nom de type et les valeurs de propriété :


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

}

L’exemple suivant illustre l’égalité des valeurs dans les enregistrements :

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

L’exemple suivant illustre l’utilisation d’une expression with pour copier un objet immuable et modifier l’une des propriétés :

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

Pour plus d’informations, consultez Records (référence C#).

Spécification du langage C#

Pour plus d'informations, voir la spécification du langage C#. La spécification du langage est la source définitive de la syntaxe C# et de l’utilisation.