Visão geral de classes, structs e registros em C#

Em C#, a definição de um tipo — uma classe, um struct ou um registro — é como um blueprint que especifica o que o tipo pode fazer. Um objeto é basicamente um bloco de memória que foi alocado e configurado de acordo com o esquema. Este artigo fornece uma visão geral desses blueprints e os respectivos recursos. O próximo artigo desta série apresenta objetos.

Encapsulamento

Encapsulamento é chamado, ocasionalmente, de primeiro pilar ou princípio da programação orientada a objeto. Uma classe ou um struct pode especificar qual membro será codificado fora da classe ou do struct. Os métodos e as variáveis que não serão usados fora da classe ou assembly poderão ser ocultados para limitar erros de codificação potenciais ou explorações maliciosas. Para obter mais informações, confira o tutorial de Programação orientada a objeto.

Membros

Os membros de um tipo incluem todos os métodos, campos, constantes, propriedades e eventos. No C#, não existem variáveis globais ou métodos como em algumas das outras linguagens. Mesmo o ponto de entrada de um programa, o método Main, deve ser declarado dentro de uma classe ou de um struct (implicitamente quando você usa instruções de nível superior).

A lista a seguir inclui todos os vários tipos de membros que podem ser declarados em uma classe, um struct ou um registro.

  • Campos
  • Constantes
  • Propriedades
  • Métodos
  • Construtores
  • Eventos
  • Finalizadores
  • Indexadores
  • Operadores
  • Tipos aninhados

Para obter mais informações, confira Membros.

Acessibilidade

Alguns métodos e propriedades devem ser chamados ou acessado pelo código fora da classe ou do struct, também conhecido como código de cliente. Outros métodos e propriedades podem ser usados apenas na classe ou struct em si. É importante limitar o acessibilidade do código para que somente o código do cliente desejado possa fazer contato. Você especifica o grau de acessibilidade dos tipos e os respectivos membros ao código do cliente usando os seguintes modificadores de acesso:

A acessibilidade padrão é private.

Herança

Classes (mas não structs) dão suporte ao conceito de herança. Uma classe que deriva de outra classe, chamada classe base, contém automaticamente todos os membros públicos, protegidos e internos da classe base, exceto seus construtores e finalizadores.

As classes podem ser declaradas como abstratas, o que significa que um ou mais dos seus métodos não têm nenhuma implementação. Embora as classes abstratas não possam ser instanciadas diretamente, elas servem como classes base para outras classes que fornecem a implementação ausente. As classes também podem ser declaradas como lacradas para impedir que outras classes herdem delas.

Para obter mais informações, consulte Herança e Polimorfismo.

Interfaces

Classes, structs e registros podem implementar várias interfaces. Implementar a partir de uma interface significa que o tipo implementa todos os métodos definidos na interface. Para obter mais informações, consulte Interfaces.

Tipos genéricos

Classes, structs e registros podem ser definidos com um ou mais parâmetros de tipo. O código do cliente fornece o tipo quando ele cria uma instância do tipo. Por exemplo a classe List<T> no namespace System.Collections.Generic é definida com um parâmetro de tipo. O código do cliente cria uma instância de um List<string> ou List<int> para especificar o tipo que a lista conterá. Para obter mais informações, consulte Genéricos.

Tipos estáticos

Classes (mas não structs ou registros) podem ser declaradas como static. Uma classe estática pode conter apenas membros estáticos e não pode ser instanciada com a palavra-chave new. Uma cópia da classe é carregada na memória quando o programa é carregado e seus membros são acessados pelo nome da classe. Classes, structs e registros podem conter membros estáticos. Para obter mais informações, consulte Classes estáticas e membros de classes estáticas.

Tipos aninhados

Uma classe, struct ou registro pode ser aninhado dentro de outra classe, struct ou registro. Para obter mais informações, consulte Tipos aninhados.

Tipos parciais

Você pode definir parte de uma classe, struct ou método em um arquivo de código e outra parte em um arquivo de código separado. Para obter mais informações, consulte Classes parciais e métodos.

Inicializadores de objeto

Você pode criar uma instância e inicializar objetos de classe ou struct e coleções de objetos, atribuindo valores às respectivas propriedades. Para mais informações, consulte Como inicializar objetos usando um inicializador de objeto.

Tipos anônimos

Em situações em que não é conveniente ou necessário criar uma classe nomeada, você usa tipos anônimos. Tipos anônimos são definidos pelos membros de dados nomeados. Para obter mais informações, consulte Tipos anônimos.

Métodos de Extensão

Você pode "estender" uma classe sem criar uma classe derivada criando um tipo separado. Esse tipo contém métodos que podem ser chamados como se pertencessem ao tipo original. Para obter mais informações, consulte Métodos de extensão.

Variáveis Locais Tipadas Implicitamente

Dentro de um método de classe ou struct, você pode usar digitação implícita para instruir o compilador para determinar o tipo de variável no tempo de compilação. Para obter mais informações, confira var (referência C#).

Registros

O C# 9 introduz o tipo record, um tipo de referência que você pode criar em vez de uma classe ou um struct. Os registros são classes com comportamento interno para encapsular dados em tipos imutáveis. O C# 10 introduz o tipo de valor record struct. Um registro (record class ou record struct) fornece os seguintes recursos:

  • Sintaxe concisa para criar um tipo de referência com propriedades imutáveis.
  • Igualdade de valor. Duas variáveis de um tipo de registro são iguais se tiverem o mesmo tipo e se, para cada campo, os valores em ambos os registros forem iguais. As classes usam igualdade de referência: duas variáveis de um tipo de classe são iguais se elas se referirem ao mesmo objeto.
  • Sintaxe concisa para mutação não destrutiva. Uma expressão with permite criar uma nova instância de registro que seja uma cópia de uma instância existente, mas com valores de propriedade especificados alterados.
  • Formatação interna para exibição. O método ToString imprime o nome do tipo de registro e os nomes e valores das propriedades públicas.
  • Suporte para hierarquias de herança em classes de registro. Classes de registro dão suporte à herança. Os structs de registro não dão suporte à herança.

Para obter mais informações, confira Registros.

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#.