Introdução aos tipos de registro em C#
Um registro em C# é uma classe ou um struct que fornece sintaxe e comportamento especiais para trabalhar com modelos de dados. O modificador record
instrui o compilador a sintetizar membros que são úteis para tipos cuja função primária é armazenar dados. Esses membros incluem uma sobrecarga de ToString() e membros que dão suporte à igualdade de valor.
Quando usar registros
Considere usar um registro no lugar de uma classe ou struct nos seguintes cenários:
- Você deseja definir um modelo de dados que depende da igualdade de valor.
- Você deseja definir um tipo para o qual os objetos são imutáveis.
Igualdade de valor
Para registros, a igualdade de valores significa que duas variáveis de um tipo de registro são iguais se os tipos corresponderem e todos os valores de propriedades e campos forem iguais. Para outros tipos de referência, como classes, igualdade significa igualdade de referência por padrão, a menos que a igualdade de valor tenha sido implementada. Ou seja, duas variáveis de um tipo de classe são iguais quando se referem ao mesmo objeto. Métodos e operadores que determinam a igualdade de duas instâncias de registro usam igualdade de valor.
Nem todos os modelos de dados funcionam bem com igualdade de valor. Por exemplo, o Entity Framework Core depende da igualdade de referência para garantir que ele use apenas uma instância de um tipo de entidade para o que é conceitualmente uma entidade. Por esse motivo, os tipos de registro não são apropriados para uso como tipos de entidade no Entity Framework Core.
Imutabilidade
Um tipo imutável é aquele que impede que você altere qualquer propriedade ou valor de campo de um objeto após ser instanciado. A imutabilidade pode ser útil quando você precisa que um tipo seja thread-safe ou que um código hash permaneça o mesmo em uma tabela de hash. Os registros fornecem sintaxe concisa para criar e trabalhar com tipos imutáveis.
A imutabilidade não é apropriada para todos os cenários de dados. O Entity Framework Core, por exemplo, não dá suporte à atualização com tipos de entidade imutáveis.
Como os registros diferem das classes e dos structs
A mesma sintaxe que declara e instancia classes ou structs pode ser usada com registros. Basta substituir a palavra-chave class
por record
, ou usar record struct
em vez de struct
. Da mesma forma, as classes de registro dão suporte à mesma sintaxe para expressar relações de herança. Os registros diferem das classes das seguintes maneiras:
- Você pode usar parâmetros posicionais em um construtor primário para criar e instanciar um tipo com propriedades imutáveis.
- Os mesmos métodos e operadores que indicam igualdade de referência ou desigualdade em classes (como Object.Equals(Object) e
==
), indicam igualdade de valor ou desigualdade nos registros. - Você pode usar uma expressão
with
para criar uma cópia de um objeto imutável com novos valores em propriedades selecionadas. - O método
ToString
de um registro cria uma cadeia de caracteres formatada que mostra o nome do tipo de um objeto e os nomes e valores de todas as propriedades públicas dele. - Um registro pode herdar de outro registro. Um registro não pode herdar de uma classe, e uma classe não pode herdar de um registro.
Os structs de registro diferem dos structs, pois o compilador sintetiza os métodos de igualdade e ToString
. O compilador sintetiza o método Deconstruct
para structs de registro posicional.
O compilador sintetiza uma propriedade public init-only para cada parâmetro de construtor primário em um record class
. Em um record struct
, o compilador sintetiza uma propriedade pública de leitura/gravação. O compilador não cria propriedades para parâmetros de construtor primário em tipos class
e struct
que não incluem modificador record
.
Exemplos
O exemplo a seguir define um registro público que usa parâmetros posicionais para declarar e instanciar um registro. Em seguida, ele imprime o nome do tipo e os valores de propriedade:
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 }
}
}
O seguinte exemplo demonstra a igualdade de valor em registros:
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
}
}
O seguinte exemplo demonstra o uso de uma expressão with
para copiar um objeto imutável e alterar uma das propriedades:
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
}
}
Para obter mais informações, confira Registros (referência de C#).
Especificação da Linguagem C#
Para obter mais informações, consulte a Especificação da linguagem C#. A especificação da linguagem é a fonte definitiva para a sintaxe e o uso de C#.
Comentários
https://aka.ms/ContentUserFeedback.
Em breve: Ao longo de 2024, eliminaremos os problemas do GitHub como o mecanismo de comentários para conteúdo e o substituiremos por um novo sistema de comentários. Para obter mais informações, consulteEnviar e exibir comentários de