Embora possa não haver uma única maneira correta de formatar o código C#, concordar com um estilo consistente em toda a equipe pode resultar em uma base de código mais limpa, legível e dimensionável. Um guia de estilo bem organizado pode ajudá-lo a controlar as discrepâncias para produzir um produto final coeso. Esta página fornece dicas e considerações importantes que devem ser levadas em conta nas convenções de nomenclatura e formatação de código ao criar seu próprio guia de estilo.
Observação: As recomendações compartilhadas aqui são baseadas naquelas fornecidas pela Microsoft. As melhores regras do guia de estilo de código são aquelas que funcionam melhor para as necessidades da sua equipe.
Você pode encontrar um exemplo de guia de estilo de código aqui ou fazer o download do e-book completo, Create a C# style guide: Escreva um código mais limpo que seja dimensionado.
Não é possível definir variáveis com espaços no nome porque o C# usa o caractere de espaço para separar identificadores. Os esquemas de caixa podem aliviar o problema de ter que usar nomes ou frases compostos no código-fonte.
Abaixo estão listadas várias convenções bem conhecidas de nomenclatura e de caixa:
Estojo Camel
Também conhecido como camel caps, o camel case é a prática de escrever frases sem espaços ou pontuação, separando as palavras com uma única letra maiúscula. A primeira letra está em minúsculas.
Normalmente, as variáveis locais e os parâmetros do método aparecem em letras maiúsculas e minúsculas. Por exemplo:
examplePlayerController
maxHealthPoints
endOfFile
Caso Pascal
O caso Pascal é uma variação do caso camel, em que a letra inicial é maiúscula. Use isso para nomes de classes e métodos no desenvolvimento do Unity. Os campos públicos também podem ser em caso pascal. Por exemplo:
ExamplePlayerController
MaxHealthPoints
EndOfFile
Caso da cobra
Nesse caso, os espaços entre as palavras são substituídos por um caractere de sublinhado. Por exemplo:
example_player_controller
max_health_points
end_of_file
Estojo de kebab
Aqui, os espaços entre as palavras são substituídos por traços. As palavras aparecem em uma espécie de "espeto" de caracteres de traço. Por exemplo:
exemplo de controlador de jogador
Max-health-points
fim do arquivo
O problema com o caso kebab é que muitas linguagens de programação usam o traço como um sinal de menos. Além disso, alguns idiomas interpretam números separados por traços como datas de calendário.
Notação húngara
O nome da variável ou da função geralmente indica sua intenção ou tipo. Por exemplo:
int iCounter
string strPlayerName
A notação húngara é uma convenção mais antiga e não é comumente usada no desenvolvimento do Unity.
Considere essas regras para suas variáveis e campos:
- Use substantivos para nomes de variáveis: Os nomes das variáveis devem ser claros e descritivos, pois representam uma coisa ou um estado específico. Use um substantivo ao nomeá-las, exceto quando a variável for do tipo bool (veja abaixo).
- Prefixar booleanos com um verbo: Essas variáveis indicam um valor verdadeiro ou falso. Muitas vezes, elas são a resposta a uma pergunta, como, por exemplo: O jogador está correndo? O jogo acabou?
- Prefixe-os com um verbo para tornar seu significado mais evidente. Geralmente, isso é associado a uma descrição ou condição, por exemplo, isDead, isWalking, hasDamageMultiplier, etc.
- Use nomes significativos. Não abrevie (a menos que se trate de matemática): Seus nomes de variáveis revelarão sua intenção. Escolha nomes que sejam fáceis de pronunciar e pesquisar.
- Embora as variáveis com uma única letra sejam adequadas para loops e expressões matemáticas, não as abrevie em outras situações. A clareza é mais importante do que o tempo economizado com a omissão de algumas vogais.
- Para uma prototipagem rápida, você pode usar temporariamente nomes curtos e "inúteis" e, posteriormente, refatorar para nomes mais significativos.
- Use letras maiúsculas e minúsculas para campos públicos e letras maiúsculas e minúsculas para variáveis privadas: Como alternativa aos campos públicos, use propriedades com um "getter" público (consulte as seções anteriores e seguintes).
- Evite muitos prefixos ou codificação especial: Você pode colocar um sublinhado (_) no prefixo das variáveis de membro privadas para diferenciá-las das variáveis locais.
- Como alternativa, use a palavra-chave this para distinguir entre variáveis de membro e locais no contexto e ignore o prefixo. Os campos e propriedades públicos geralmente não têm prefixos.
- Alguns guias de estilo usam prefixos para variáveis de membro privado (m_), constantes (k_) ou variáveis estáticas (s_), para que o nome possa revelar mais sobre a variável em um piscar de olhos.
- Muitos desenvolvedores evitam esses recursos e usam o Editor. No entanto, nem todos os IDEs oferecem suporte ao realce e à codificação por cores, e algumas ferramentas não conseguem mostrar o contexto avançado de forma alguma. Considere isso ao decidir como (ou se) vocês aplicarão os prefixos juntos como uma equipe.
- Especifique (ou omita) modificadores de nível de acesso de forma consistente: Se você deixar de fora o modificador de acesso, o compilador assumirá que o nível de acesso deve ser privado. Isso funciona bem, mas seja consistente na forma como você omite o modificador de acesso padrão.
- Lembre-se de que você precisará usar protected se quiser fazer isso em uma subclasse posteriormente.
Os enums são tipos de valores especiais definidos por um conjunto de constantes nomeadas. Por padrão, as constantes são números inteiros, contados a partir de zero.
Use letras maiúsculas e minúsculas para nomes e valores de enum. Você pode colocar enums públicas fora de uma classe para torná-las globais. Use um substantivo no singular para o nome do enum.
Observação: Enums bit a bit marcados com o atributo System.FlagsAttribute são a exceção a essa regra. Normalmente, você os pluraliza, pois eles representam mais de um tipo.
Siga estas regras padrão ao nomear suas classes e interfaces:
Use substantivos em letras maiúsculas e minúsculas para os nomes das classes: Isso manterá suas aulas organizadas.
Se você tiver um MonoBehaviour em um arquivo, o nome do arquivo de origem deverá corresponder: Você pode ter outras classes internas no arquivo, mas deve haver apenas um MonoBehaviour por arquivo.
Prefixe os nomes das interfaces com um "I" maiúsculo: Em seguida, use um adjetivo que descreva a funcionalidade.
No C#, cada instrução executada é realizada no contexto de um método.
Os métodos executam ações, portanto, aplique essas regras para nomeá-los adequadamente:
Inicie o nome com um verbo: Adicione contexto, se necessário (por exemplo, GetDirection, FindTarget, etc.)
Use letras maiúsculas e minúsculas para os parâmetros: Formatar parâmetros passados para o método como variáveis locais.
Os métodos que retornam bool devem fazer perguntas: Assim como as próprias variáveis booleanas, prefixe os métodos com um verbo se eles retornarem uma condição de verdadeiro-falso. Isso os expressa na forma de uma pergunta (por exemplo, IsGameOver, HasStartedTurn).
Observação: Os termos "função" e "método" são frequentemente usados de forma intercambiável no desenvolvimento do Unity. No entanto, como não é possível escrever uma função sem incorporá-la a uma classe no C#, "método" é o termo correto.
Os eventos em C# implementam o padrão de observador. Esse padrão de design de software define um relacionamento no qual um objeto, o sujeito (ou editor), pode notificar uma lista de objetos dependentes chamados observadores (ou assinantes). Assim, o sujeito pode transmitir alterações de estado para seus observadores sem acoplar fortemente os objetos envolvidos.
Existem vários esquemas de nomenclatura para eventos e seus métodos relacionados no assunto e nos observadores. Experimente as práticas das seções a seguir.
Nomeie o evento com uma frase verbal. Certifique-se de escolher um que comunique a mudança de estado com precisão.
Use o particípio presente ou passado para indicar o estado dos eventos como antes ou depois. Por exemplo, especifique "OpeningDoor" para um evento antes de abrir uma porta e "DoorOpened" para um evento depois.
Use o delegado System.Action para eventos. Na maioria dos casos, o Action<T> pode manipular os eventos necessários para a jogabilidade.
Você pode passar até 16 parâmetros de entrada de tipos diferentes com um tipo de retorno de void. Usar o delegado predefinido economiza código.
Observação: Você também pode usar o EventHandler ou EventHandler<TEventArgs> delegados. Chegue a um acordo com a equipe sobre como todos devem implementar os eventos.
Prefixe o método de captação de eventos (no assunto) com "On". O sujeito que invoca o evento normalmente o faz a partir de um método com o prefixo "On" (por exemplo, "OnOpeningDoor" ou "OnDoorOpened").
Prefixe o método de tratamento de eventos (no observador) com o nome do sujeito e um sublinhado (_). Se o assunto for chamado de "GameEvents", seus observadores poderão ter um método chamado "GameEvents_OpeningDoor" ou "GameEvents_DoorOpened".
Decida sobre um esquema de nomenclatura consistente para a sua equipe e implemente essas regras no seu guia de estilo.
Observação: Esse "método de tratamento de eventos" não deve ser confundido com o delegado EventHandler.
Crie EventArgs personalizados somente se necessário. Se você precisar passar dados personalizados para seu evento, crie um novo tipo de EventArgs, herdado de System.EventArgs ou de uma estrutura personalizada.
Use namespaces para garantir que suas classes, interfaces, enums etc. não entrem em conflito com aquelas já existentes em outros namespaces ou no Global Namespace. Os namespaces também podem evitar conflitos com assets de terceiros da Unity Asset Store ou outras cenas de teste que não farão parte da versão final do projeto.
Ao aplicar namespaces:
Use letras maiúsculas e minúsculas sem símbolos especiais ou sublinhados.
Adicione uma diretiva using na parte superior do arquivo para evitar a digitação repetida do prefixo do namespace.
Crie também subespaços de nome. Use o operador ponto(.) para delimitar os níveis de nome, permitindo que você organize seus scripts em categorias hierárquicas. Por exemplo, você pode criar "MyApplication.GameFlow", "MyApplication.AI", "MyApplication.UI" e assim por diante, para manter diferentes componentes lógicos do seu jogo.
No código, essas classes são chamadas de Enemy.Controller1 e Enemy.Controller2, respectivamente. Adicione uma linha de uso para evitar a digitação do prefixo (por exemplo, usando Enemy;).
Quando o compilador encontra os nomes de classe Controller1 e Controller2, ele entende que você quer dizer Enemy.Controller1 e Enemy.Controller2.
Se o script precisar fazer referência a classes com o mesmo nome de namespaces diferentes, use o prefixo para diferenciá-las. Por exemplo, se você tiver uma classe Controller1 e Controller2 no namespace Player, poderá escrever Player.Controller1 e Player.Controller2 para evitar conflitos. Caso contrário, o compilador informará um erro.
Obtenha mais dicas de estilo de código
Saiba mais sobre a formatação geral aqui ou confira o e-book completo. Você também pode explorar nosso exemplo de guia de estilo de código.