Regras e convenções de nomenclatura do identificador C#

Um identificador é o nome que você atribui a um tipo (classe, interface, struct, delegado ou enumerado), membro, variável ou namespace.

Regras de nomenclatura

Os identificadores válidos devem seguir essas regras. O compilador de C# produz um erro para qualquer identificador que não siga estas regras:

  • Os identificadores devem começar com letra ou sublinhado (_).
  • Os identificadores podem conter caracteres de letra Unicode, caracteres de dígitos decimais, caracteres de conexão Unicode, caracteres de combinação Unicode ou caracteres de formatação Unicode. Para obter mais informações sobre as categorias Unicode, consulte o Banco de dados da categoria Unicode.

É possível declarar identificadores que correspondem às palavras-chave em C# usando o prefixo @ no identificador. O @ faz parte do nome do identificador. Por exemplo, @if declara um identificador chamado if. Esses identificadores textuais são destinados principalmente para interoperabilidade com os identificadores declarados em outras linguagens.

Para obter uma definição completa de identificadores válidos, confira o artigo Identificadores na especificação da linguagem C#.

Importante

A especificação da linguagem C# permite apenas as categorias de letras (Lu, Ll, Lt, Lm, Lo ou Nl), dígitos (Nd), a conexão (Pc), a combinação (Mn ou Mc) e a formatação (Cf). Qualquer coisa fora disso será automaticamente substituída usando _. Isso pode afetar determinados caracteres Unicode.

Convenções de nomenclatura

Além das regras, as convenções para nomes de identificador são usadas em todas as APIs do .NET. Essas convenções fornecem consistência para nomes, mas o compilador não as impõe. Você é livre para usar convenções diferentes em seus projetos.

Por convenção, os programas C# usam PascalCase para nomes de tipo, namespaces e todos os membros públicos. Além disso, a equipe dotnet/docs usa as seguintes convenções, adotadas a partir do estilo de codificação da equipe do .NET Runtime:

  • Os nomes de interface começam com I maiúsculo.

  • Os tipos de atributo terminam com a palavra Attribute.

  • Os tipos enumerados usam um substantivo singular para nonflags e um substantivo plural para sinalizadores.

  • Os identificadores não devem conter dois caracteres de sublinhado (_) consecutivos. Esses nomes estão reservados para identificadores gerados por compilador.

  • Use nomes significativos e descritivos para variáveis, métodos e classes.

  • Prefira clareza em vez de brevidade.

  • Use PascalCase para nomes de classe e nomes de método.

  • Use CamelCase para parâmetros de método e variáveis locais.

  • Use PascalCase para nomes de constantes, tanto para constantes de campo quanto para constantes de local.

  • Os campos de instância privada começam com um sublinhado (_) e o texto restante usa CamelCase.

  • Os campos estáticos começam com s_. Essa convenção não é o comportamento padrão do Visual Studio, nem parte das Diretrizes de design de estrutura, mas é configurável no editorconfig.

  • Evite usar abreviações ou acrônimos em nomes, exceto para abreviações amplamente conhecidas e aceitas.

  • Use namespaces significativos e descritivos que seguem a notação de nome de domínio inverso.

  • Escolha os nomes de assembly que representam a finalidade primária do assembly.

  • Evite usar nomes de letra única, exceto para contadores de loop simples. Além disso, os exemplos de sintaxe que descrevem a sintaxe de constructos C# geralmente usam os seguintes nomes de letra única que correspondem à convenção usada na especificação da linguagem C#. Os exemplos de sintaxe são uma exceção à regra.

    • Use S para structs, C para classes.
    • Use M para métodos.
    • Use v para variáveis, p para parâmetros.
    • Use r para parâmetros ref.

Dica

Você pode impor convenções de nomenclatura que dizem respeito à capitalização, prefixos, sufixos e separadores de palavras usando regras de nomenclatura de estilo de código.

Nos exemplos a seguir, as diretrizes relativas aos elementos marcados com public são também aplicáveis ao trabalhar com elementos protected e protected internal, todos os quais devem ser visíveis para chamadores externos.

Pascal case

Use pascal casing ("PascalCasing") ao nomear um tipo class, interface, struct ou delegate.

public class DataService
{
}
public record PhysicalAddress(
    string Street,
    string City,
    string StateOrProvince,
    string ZipCode);
public struct ValueCoordinate
{
}
public delegate void DelegateType(string message);

Ao nomear um interface, use Pascal Case, além de aplicar ao nome um prefixo I. Esse prefixo indica claramente aos consumidores que ele é um interface.

public interface IWorkerQueue
{
}

Ao nomear membros public de tipos, como campos, propriedades, eventos, use pascal casing. Além disso, use pascal casing para todos os métodos e funções locais.

public class ExampleEvents
{
    // A public field, these should be used sparingly
    public bool IsValid;

    // An init-only property
    public IWorkerQueue WorkerQueue { get; init; }

    // An event
    public event Action EventProcessing;

    // Method
    public void StartEventProcessing()
    {
        // Local function
        static int CountQueueItems() => WorkerQueue.Count;
        // ...
    }
}

Ao gravar registros posicionais, use Pascal Case para parâmetros, pois são as propriedades públicas do registro.

public record PhysicalAddress(
    string Street,
    string City,
    string StateOrProvince,
    string ZipCode);

Para obter mais informações sobre registros posicionais, confira Sintaxe posicional para definição de propriedade.

Camel Case

Use camel casing ("camelCasing") ao nomear campos private ou internal e dê a eles o prefixo _. Use camel casing ao nomear variáveis locais, incluindo instâncias de um tipo delegado.

public class DataService
{
    private IWorkerQueue _workerQueue;
}

Dica

Ao editar o código do C# que segue essas convenções de nomenclatura em um IDE que permite a conclusão da instrução, digitar _ mostrará todos os membros no escopo do objeto.

Ao trabalhar com os campos static que são private ou internal, use o prefixo s_ e, para thread estático, use t_.

public class DataService
{
    private static IWorkerQueue s_workerQueue;

    [ThreadStatic]
    private static TimeSpan t_timeSpan;
}

Ao gravar os parâmetros de método, use Camel Case.

public T SomeMethod<T>(int someNumber, bool isValid)
{
}

Para obter mais informações sobre convenções de nomenclatura em C#, confira o estilo de codificação da equipe do .NET Runtime.

Diretrizes para a nomenclatura de parâmetros de tipo

As diretrizes a seguir se aplicam a parâmetros de tipo em parâmetros de tipo genérico. Parâmetros de tipo são os espaços reservados para argumentos em um tipo genérico ou um método genérico. Você pode ler mais sobre parâmetros de tipo genérico no guia de programação em C#.

  • Nomeie parâmetros de tipo genérico com nomes descritivos, a menos que um nome de letra única seja completamente autoexplicativo e um nome descritivo não adicione valor.

    public interface ISessionChannel<TSession> { /*...*/ }
    public delegate TOutput Converter<TInput, TOutput>(TInput from);
    public class List<T> { /*...*/ }
    
  • Considere usar T como o nome do parâmetro de tipo para tipos com um parâmetro de tipo de letra única.

    public int IComparer<T>() { return 0; }
    public delegate bool Predicate<T>(T item);
    public struct Nullable<T> where T : struct { /*...*/ }
    
  • Insira o prefixo “T” em nomes descritivos de parâmetro de tipo.

    public interface ISessionChannel<TSession>
    {
        TSession Session { get; }
    }
    
  • Considere indicar as restrições colocadas em um parâmetro de tipo no nome do parâmetro. Por exemplo, um parâmetro restrito a ISession pode ser nomeado como TSession.

A regra de análise de código CA1715 pode ser usada para garantir que os parâmetros de tipo sejam nomeados adequadamente.

Convenções de nomenclatura extras

  • Em exemplos que não incluem o uso de diretivas, use as qualificações do namespace. Se você souber que um namespace é importado por padrão em um projeto, não precisará qualificar totalmente os nomes desse namespace. Os nomes qualificados poderão ser quebrados após um ponto (.) se forem muito longos para uma única linha, conforme mostrado no exemplo a seguir.

    var currentPerformanceCounterCategory = new System.Diagnostics.
        PerformanceCounterCategory();
    
  • Não é necessário alterar os nomes de objetos que foram criados usando as ferramentas de designer do Visual Studio para adequá-los a outras diretrizes.