6 maneiras de fazer a mesma coisa, o que é considerado boas práticas?

As vezes tem tantas maneiras diferentes de fazer o mesmo código que nós ficamos na dúvida quanto a qual maneira usar. O que seria considerado "boa prática" pela comunidade e o que sua equipe entenderia melhor. Suponhamos que você esteja trabalhando dentro de um método de um Domain Service chamado UmDomainServiceChique(objetoDoDominio) que será chamado por uma API. Você tem uma regra de negócio chique para ser verificada que por enquanto chamarei de VerificaMinhaRegraChiqueComplexa(). Você chama UmDomainServiceChique(objetoDoDominio) e caso VerificaMinhaRegraChiqueComplexa() retorne true você vai querer que UmDomainServiceChique faça o que tem que fazer e a api retornar Ok 200, caso contrário você quer que a API responda um erro qualquer, tipo BadRequest, e retornar uma mensagem dizendo que VerificaMinhaRegraChiqueComplexa deu ruim. Eu vejo 6 maneiras de fazer isso, gostaria de saber a opinião de outrs devs sobre qual seria a maneira menos gambiarr

Modernos padrões de nomenclatura de codificação

     Os padrões apresentados aqui são fruto de uma pesquisa em 2 livros e 4 sites, experiências profissionais do autor, consenso do mercado e recomendações de práticas da Microsoft. Como qualquer convenção ou tecnologia, este não é 100% correto, não é uma verdade absoluta e não é uma bala de prata. São apenas guidelines para que todos nós escrevamos bom código, código limpo e livre de bad smells e que possamos entender e melhorar os códigos uns dos outros, evoluindo como equipe. Nesse texto eu quis expressar não somente regras de nomenclatura e codificação, mas também apresentar algumas boas práticas para um código mais coeso e flexível.
     Esses são os padrões que adotamos na empresa onde trabalho e não há nenhum motivo especial para você e sua equipe adotarem este. Os padrões de codificação devem ser um consenso da equipe.
     Estes foram elaborados com ajuda de outros padrões prontos de outras empresas, unindo o que eu achei de melhor nos padrões da Microsoft e nas práticas já consolidadas da comunidade.

   

"É impossível para um homem aprender aquilo que ele acha que já sabe."                                                                                                                     - Epíteto



     Em se definindo e aplicando “Padrões de Codificação e Documentação”, há um enorme ganho com facilidade de implementação e melhorias no código em:

  • Visibilidade;
  • Portabilidade;
  • Reaproveitamento;
  • Redução de tempo em:
  • Adaptação de novos desenvolvedores.
  • Manutenção;
  • Migração;
  • Identificação, rastreamento e correção de erros.
  • Diminuição de reescrita de código por falta de documentação.


Fonte: http://blog.walkeralencar.com/archives/233


     Coding standards tem sido alvo de várias disciplinas, e tratado em vários livros de programação e boas práticas. Alguns livros que abordam o tema são livros de XP e o Código Limpo, ambos abordando outros aspectos do bom código e da disciplina dos programadores além do aspecto dos padrões de codificação.

     A própria microsoft já fornece, em seu principal veículo de comunicação, msdn, os padrões de codificação. Isso garante, por exemplo, que qualquer programador recém-contratado do mercado já esteja hasbituado com os padrões de codificação.
https://msdn.microsoft.com/en-us/library/ff926074.aspx
Recomendo a adoção deste padrão com algumas alterações muito comuns na comunidade.

   

Nossas Regras

     A regra geral é seguir as convenções e práticas do próprio .net framework (que foram adotadas como padrão pelo mercado) e manter a consistência.


     Definições de casing conventions:

          PascalCase/UpperCamelCase  - Consiste em começar com maiúscula e usar maiúscula na inicial de cada palavra composta. Exemplo: FuncionarioMensalista
Geralmente é utilizada para nomear propriedades e campos públicas e métodos (públicos ou privados). Também deve ser usado para nomear constantes.

          camelCase - Consiste em se iniciar com minúscula e usar maiúscula para a primeira letra de cada palavra composta. Exemplo: funcionarioMensalista
          Geralmente são usados em nomes de variáveis locais e propriedades privadas.


     Notação Húngara

          Os padrões de nomenclatura da comunidade C# em geral dizem para não confiar o tipo de uma variável a seu nome:
"Do not rely on the variable name to specify the type of the variable. It might not be correct."
           Isso põe por terra todo o conceito antiquado de notação húngara.  ( http://pt.wikipedia.org/wiki/Nota%C3%A7%C3%A3o_h%C3%BAngara )
          Outras coisas que põe por terra a notação húngara são as boas práticas de se criar nomes significativos para variáveis e métodos (XP, Código Limpo), que expressem ação e intenção e que dispensam comentários.
          Outra crescente desvantagem da notação húngara é que com os frameworks e ides cada vez mais completos um número cada vez maior de classes prontas, componentes e widgets vêm empacotados com os produtos que usamos (visual studio e .net framework) fora os adquiridos de terceiros e os open-source.
          Criar uma abreviação de duas ou três letras para cada tipo destes torna-se um verdadeiro inferno.
          Notação húngara já é um conceito bem antigo e com certeza seu uso traz muitas desvantagens. Tipos dinâmicos e definição de tipo em runtime perdem todo o sentido com notação húngara, e não é necessário visto que a IDE pode vasculhar e te mostrar todos os atributos de uma variável.
          Quando você cria suas classes você cria seus tipos de dados com lógica própria. E frequentemente renomeamos nossas classes, mudamos, extraímos uma da outra, juntamos, derivamos. Fica impossível arrumar uma abreviação consistente para todas elas.


     Noções gerais ausentes no padrão da Microsoft

           Embora os padrões da microsoft abordem o tema das chaves, arrays, linhas e espaços em branco (assuntos ausentes nos nossos padrões), ela não aborda os padrões de nomenclatura (definidos como notação húngara nos nossos padrões mais antigos).
           É uma prática comum nas linguagens derivadas de c, ao se nomear campos privados dos quais dependem propriedades (públicas ou privadas), nomear em lowerCamelCase precedido de _.
           Outra prática comum é nomear constantes todas em MAIUSCULAS. Isso torna claro que o identificador é somente leitura, além de tornar claro seu tipo e que está relacionado à uma regra de negócio e não à arquitetura do software ou da informação, porém existem recomendações no mercado para não usá-las, portanto seguiremos as recomendações e não usaremos. Nomes de constantes em maiúsculas atraem muito a atenção do programador, distraindo-o, além de não ser consistente com o .net framework.
           Não se deve usar _ entre as palavras de um método, priopriedade ou variáveis, no entanto isso pode ser tolerado em uma constante.
          Um nome deve identificar um elemento (quem ele é) e não generalizá-lo. Além disso deve indicar o que o elemento faz e para que serve, não o que ele é.


     Metáfora

          Todo sistema deve ter uma metáfora que o defina em poucas palavras. Isso ajuda a equipe a formar um vocabulário comum do domínio da aplicação (ou das aplicações) e falarem a mesma língua. Também ajuda na escolha de bons nomes para os projetos e seus componentes. Bons nomes são essenciais para um software coeso e auto-documentável. Bons nomes dispensam comentários ou documentações complexas. Se for gastar um tempo desenvolvendo um software, comece  gastando um bom tempo para o seu nome. O mesmo vale para uma classe ou método: tome tempo para escolher um bom nome. Isso te ajudará a manter o princípio da responsabilidade única  e o princípio da segregação de interface.
          Use nomes significativos e pronunciáveis. Use nomes que expressem propósito.
          Sistemas amplamente usados são baseados em metáforas, por exemplo o sistema de arquivos do Windows é baseado na metáfora do Arquivo (armários para se guardar fichas / pastas).
          Essas ideias estão em acordo com os princípios do XP e do DDD.


     Solution          

          A solution pode agrupar uma série de projetos / programas que são parte de um mesmo sistema, por isso dê um nome para a solution condizente com a metáfora do sistema. A ideia expressa pela solution deveria ser compartilhada pelos seus projetos.
          Exemplo: ServiceDesk
   

     Projetos

          Use a solution como base ou prefixo para o nome dos projetos, e coloque seu objetivo e/ou ambiente como sufixo. Se o seu projeto for dividido em camadas físicas, como Core, DAL/Data, Domain, GUI use esses nomes para identificar a camada a que pertence o projeto.
          Exemplo: ServiceDesk.Web


     Arquivos

          Salvo raras exceções, cada arquivo.cs deve ter apenas uma classe, e o nome do arquivo deve ser o nome desta classe. Uma exceção são os arquivos de partial classes, esses devem ter um sufixo que identifiquem o propósito do arquivo ou o porque dele estar separado. Por exemplo designer ou generated
          Exmeplos: Default.cs Default.design.cs
          Porque: isso é consistente com as práticas da Microsoft no source do próprio .net. Arquivos são ordenados alfabeticamente pelo SO, e isso ajuda arquivos de classes parciais a permanecerem adjacentes.


     Namespaces

          Use PascalCase para nomear os namespaces. Use uma estrutura clara e bem definida.
          Exemplo: NomeDaEmpresa.NomeDoProjeto.NomeDaCamada.NomeDoModulo.NomeDoComponente
                         BBI.ServiceDesk.Web.Data.Services.Repository
          Porque: é consistente com as práticas da Microsoft e mantém uma boa organização da sua base de código.


     Classes

          Use PascalCase para nomear classes. Use substantivos ou predicados nominais em caso de palavras compostas. Não use verbos.
          Exemplo: Funcionario, GrupoDeFuncionario, ProdutoComposto
          Porque: classes são tipos de objetos, mini programas, devem expressar um conceito e não uma ação. Um conceito é melhor expresso por substantivos e adjetivos do que por verbos. Isso é consistente com as práticas da Microsoft e mais fácil de ler.


     Interfaces

          Use PascalCase para nomear interfaces, mas prefixe as mesmas com I. Isso ajuda a diferenciar interfaces de classes abstratas ou outros tipos de dados, ajuda a identificar o que as classes que as implementam fazem, e é uma prática comum do mercado desde a época do COM/COM+.
          Use substantivos, predicados nominais ou adjetivos/advérbios para nomear interfaces.
          Exemplos: IEnumerable, IList, IHierarchyData, IEntity
          Porque: Isso é consistente com os padrões da Microsoft e do COM/COM+, além disso interfaces podem ser usadas para decorar classes, como flags, ou usadas como atributos. Por issp interfaces podem ser nomeadas com adjetivos ou advérbios, pois elas modificam ou segregam comportamento de outras classes.
          Interfaces são a base da abstração e da segregação de responsabilidade. São contratos entre duas partes, ou pontos de encaixe entre componentes. Programe orientado a interfaces e não à implementação.


   

     Ordem dos elementos

          Declare todas as variáveis membro no topo da classe, com as estáticas acima de todas. Utilize a ordem:
          Membros/Fileds


  1.   privadas estáticas
  2.   públicas estáticas (evite-os a todo custo)
  3.   privadas de instância
  4.   públicas de instância (evite-os, transforme-os em propriedades sempre que possível)
  5.   propriedades protegidas
  6.   propriedades públicas de instância



         Métodos (na ordem do mais genérico/abstrato para o mais específico, dos métodos que chamam outros para os chamados)


  1.  Construtores e Destrutores 
  2.  Factory methods públicos de classes (são construtores especializados)
  3.  Métodos públicos de classe
  4.  Métodos privados de classe
  5.  Métodos públicos de instância
  6.  Métodos protegidos de instância
  7.  Métodos privados de instância


          Porque: é uma prática geralmente aceita, evite que se fique procurando por variáveis, garante que a leitura de um source seja como a leitura de um artigo de jornal: dados genéricos em cima, dados detalhados abaixo, com nível crescente de granularidade e decrescente de abstração de cima para baixo. Para isso os métodos que são chamados por outras classes ficam acima, e os chamados pela própria classe abaixo. Com isso você precisa ler apenas o topo da classe para saber o que ela faz e como ela funciona apenas visualizando sua interface implícita sem se aprofundar em sua implementação.


     Propriedades (privadas/protegidas/públicas)

          Use PascalCase para o nome de propriedades. Use preferencialmente substantivos e predicados nominais.
          Exemplo: Nome, DataNascimento
          Porque: além de facilitar a leitura, trata-se de objetos pertencentes a outro, como peças de algo maior, portanto todos substantivos. Está de acordo com as práticas da Microsoft para o .net
   

     Fields ou Variáveis de instância ou Member Variables


  •            Públicos : não devem existir
  •            Privados: aplicar camelCase precedido de _

          Exemplo: _dataNascimento 
          Porque: Está em acordo com as práticas comuns do mercado para linguagens derivadas de _, ajuda a separar os campos privados dos argumentos de métodos / constructors sem a necessidade do uso do this, isola essas variáveis da digitação acidental (porque obriga a digitação do _ no início, excluindo-as do intellisense / autocomplete).


     Variaveis Locais

          Use camelCase para os nomes de variáveis locais, use nomes significativos, evite prefixos e abreviações a não ser que sejam bem conhecidas, não use notação polonesa.
          Exemplo: enderecoServidor, connectionString
          Porque: além de ser fácil de ler é consistente com a metodologia da Microsoft


     Métodos

          Use PascalCase para nomear os métodos. Use o formato Verbo ou Verbo+Complemento para nomear os métodos. Se o verbo for intransitivo o método não deveria ter parâmetros.
          Exemplo:  Salvar(grupoDeFuncionario)
                         Excluir(tipoDeTarefa)
                         ListarEntreDatas(dataInicial, dataFinal)
          Porque: Consistente com o .net framework e fácil de ler. Verbos expressam ações, por isso são melhores que substantivos para expressar métodos. É natural se ler e escrever dessa forma



     Argumentos de Métodos

          Use camelCase para argumentos de métodos, use substantivos. Se o nome de um método contém um verbo, os argumentos devem ser complementos desse verbo.
          Exemplo: CalcularReajuste(porcentagemAumento)
                         Salvar(grupoDeFuncionario)
                         Excluir(tipoDeTarefa)
                         ListarEntreDatas(dataInicial, dataFinal)
          Porque: mais fácil de ler e entender. Tudo que pode ser verbalizado pode ser melhor armazenado pelo nosso cérebro. É condizente com as práticas da Microsoft no .net.


    Ainda Sobre Argumentos de Métodos

          Se você precisar de de mais de 3 argumentos no seu método e/ou precisar usar parâmetros nomeados há uma grande chance de você estar simplesmente enrolado e seu método precisar ser refatorado. Verifique se seu método não está com responsabilidades demais.
          Se você passa argumentos booleanos ou enums para um método onde ele tomará uma ação diferente dependendo do parâmetro é uma evidência clara de que você precisa decompor este em dois ou mais métodos. Dê uma olhada nos padrões de projeto GOF "Template Method" e "Strategy" que eles podem de dar uma ideia de como refazer estes métodos.
          Porque: Métodos grandes são difíceis de ler e de manter. Eles tendem a crescer mais a cada manutenção com a adição de desvios condicionais para fazerem coisas diferentes dependendo de configuração ou parâmetros. Esses métodos degradam o sistema rapidamente, ficando com código inatingível (nunca executado), código comentado e código com side effects (statefull) que não podem ser testados.


     Parâmetros-Tipo (type parameters)

          Type Parameters são os parâmetros que representam um tipo em uma expressão que usa generics. Por exemplo na definição de List<T>   T é o type parameter. Na definição de classes genéricas sempre use PascalCase precedido de T para nomear os type parameters.
          Exemplo: Repository<TEntity> : IRepository<TEntity> where TEntity : Entity

    Strings

          Concatene strings pequenas com sinal de " + " porém use StringBuilder para strings grandes. Use string.Format para strings pré formatadas e substituição de placeholders.
          Porque: Embora tenha sobrecarga de operadores nativa para parecer um value type pimitivo as strings são objetos (reference types). Isso significa que a cada atribuição ou concatenação de duas strings, dois objetos são destruídos  e um novo é criado. Isso cria um grande overhead, principalmente dentro de loops. StringBuilder é uma classe que concatena várias strings de uma só vez sem precisar destruir e recriar a cada adição fazendo um uso mais inteligente da memória. Foi feito para ser usado em loops onde muitas strings são concatenadas, como uma saída html por exemplo.



    Enums

          Use PascalCase. Use substantivos no singular se for um Enum comum. Se for um Enum do tipo bit field / flags (a serem combinados múltiplos valores com o operador "|") pode-se usar substantivos no plural, pois sugere que mais de um valor pode ser usado.
          Exemplo:
enum Importance
{
None,
Trivial,
Regular,
Important,
Critical
}; 

          Porque: Consistente com o .net framework e mais natural para ler


     if ... else if ... else

               Sempre coloque um bloco de código com { } em estruturas de decisão if pulando uma linha antes de { e outra ante de }. Mesmo com if's que só terão uma linha de código.
               Se você precisar de mais de 3 níveis de aninhamento para uma estrutura if ou case significa que você está enrolado. Provavelmente seu método faz coisas demais ou sua classe tem muitas responsabilidades e muitos motivos pra mudar.  
            Porque: if (b1) if (b2) Foo(); else Bar(); // consegue dizer ao primeiro golpe de vista a qual if pertence o else?      


     Case ... default

               Sempre tenha um label default em uma estrutura case. Mesmo se ele nunca devesse ser atingido. Coloque nele código para disparar uma exceção caso um parâmetro inválido tenha sido erroneamente enviado para o case analizar.



     Loops

               Se você precisar de dois níveis de loops aninhados considere transformar o mais interno em um método privado. Se você estiver trabalhando com mais 3 níveis verifique se o método e/ou a classe não estão com responsabilidades demais e se não estão intestáveis.
               Jamais altere a variável de controle do loop for ou foreach dentro do loop. Isso pode levar a loops infinitos.



     Alinhamento vertical de chaves

          Alinhe as  chaves verticalmente. Não mantenha a chave no final da linha, quebre a linha antes da chave e mantenha elas alinhadas. Sempre abra e feche as chaves em novas linhas.
          Certo:
         public virtual void setMensagemExplicacao( string mensagem)
        {
            MensagemExplicacao = mensagem;
            lgdExplicacao.Visible = true;
            lgdExplicacao.InnerText = mensagem;
        }

          Errado:
         public virtual void setMensagemExplicacao( string mensagem){
            MensagemExplicacao = mensagem;
            lgdExplicacao.Visible = true;
            lgdExplicacao.InnerText = mensagem;
        }

         public virtual void setMensagemExplicacao( string mensagem){
            MensagemExplicacao = mensagem;
            lgdExplicacao.Visible = true ;
            lgdExplicacao.InnerText = mensagem;}

          Porque:   Chaves abertas ou fechadas no final de uma linha de código passam despercebidas e não são legíveis. O código pode ser confundido como parte do código acima.


     Espaços em branco

          Deixe espaços em branco entre os operadores e seus operandos. Isso facilita a leitura.    
          Deixe espaços em branco entre um if, for ou foreach e sua expressão. Exemplo: if (UmFuncionario.Equals(EsteFuncionario))
       

     Quebra de linhas

          Quebre linhas antes de abertura e fechamento de chaves, quebre linhas para separar ideias, agrupar conceitos relacionados, separar conceitos não relacionados, separar a declaração de variáveis de seu uso, quebrar cadeias longas de caracteres ou encadeamentos longos de chamadas de métodos ou propriedades.
          Também é bom quebrar as linhas em chamadas de funções com listas de parâmetros muito longas, e edentar esses parâmetros.
          Quebre linhas antes e depois de regions, antes e depois de um using, e separando os fornecedores na lista de usings.

     Regions

          Use regions para agrupar conceitos e separar interface de implementação, eventos de métodos e de variáveris.
          Não use regions aninhadas pois isso impõe complexidade desnecessária.
          Não use regions para esconder código comentado, sujeira e gambiarras.

     Indentação/Recuo

          Use a indentação padrão do C# no visual studio (um tab = 4 espaços). Indente conceitos subordinados. Se precisar separar cadeias longas de chamadas em linhas, ou cadeias longas de parâmetros quebradas em linhas. Quebre as linhas de uma sentença SQL e Intente o SQL.
          Exemplo:
            ChamadaDeFuncao(
                 par1,
                 par2,
                 par3,
                 par4,
                 par5,
                 par6);
            {
                 //código
            }
                               Modulo obj = session
                            .CreateCriteria< Modulo>()
                            .SetTimeout(120)
                            .SetLockMode( LockMode.None)
                            .SetCacheable( true)
                            .Add( Restrictions.Eq("Nome" , nome))
                            .UniqueResult< Modulo>();
     

     Comentarios

           Algumas definições dos nossos padrões foram feitas para VB antigo e se chocam diretamente com os padrões da microsoft, por exemplo o padrão de comentários:
"Do not create formatted blocks of asterisks around comments."
          Há comentários que prejudicam a legibilidade do código, não são atualizados no mesmo ritmo do código, sujam o mesmo e poderiam facilmente ser substituídos por nomes significativos
          Há comentários que simplesmente perdem o sentido pouco tempo depois de terem sido colocados, simplesmente porque o código logo abaixo deles ou o objetivo do sistema em si foi mudado.
          Não comente o código simplesmente para desativá-lo esperando que um dia vá precisar dele. Antes de dar check-in, delete o código comentado. Código comentado apenas emporcalha o sistema, deteriorando-o mais rápido. Outros programadores acharão que é importante e evitarão removê-lo. Se um dia, quando ele não for mais útil, ele acidentalmente for descomentado ele pode comprometer todo o funcionamento do sistema. Confie no seu sistema de versionamento.
          Não coloque cabeçalhos com informações de autor, versionamento, changelog e bugtracking em comentários. Confie no seu sistema de versionamento, faça os comentários de changelog ao dar check-in no sistema, controle o bugtracking com um sistema apropriado. Uma exceção à regra é quando há motivos legais para assegurar o  autor do código, então pode existir um cabeçalho com o autor.
          Não comente o óbvio, coisas muito simples ou muito bem  estabelecidas. Se um comentário óbvio se faz necessário, então na verdade é necessário renomear seu método para um nome que expresse seu propósito.
          Quando necessário, comente em uma linha separada (geralmente acima) e não na linha do código
          Comece o comentário com letra maiúscula e termine com um ponto
          Insira um espaço entre o // e o início do comentário


     Comentários de documentação

          Comentários de documentação são precedidos por /// e servem para definir a estrutura e uso de classes, métodos e propriedades para geração de documentação automática com ferramentas como Doxygene, NDoc e SandCastle.
          Como seu objetivo é documentar uma interface implícita ou API para uso de outros programadores, comente apenas métodos e propriedades públicos e nunca comente membros privados.
          Porque: Isso está de acordo com o Princípio SOLID de programar voltado a interfaces e não implementação. Você não quer que outros programadores usem os métodos privados, então não há necessidade deles aparecerem na documentação. Assim você encapsula e protege o source em um nível adicional e está livre para mudar a implementação contanto que mantenha a mesma interface e funcionalidade.



     Try ... Finally

          Use o using sempre que seu bloco try ... finally servir apenas para chamar dispose em um recurso não gerenciado.
          Exemplo:
// This try-finally statement only calls Dispose in the finally block.
Font font1 = new Font("Arial", 10.0f);
try
{
    byte charset = font1.GdiCharSet;
}
finally
{
    if (font1 != null)
    {
        ((IDisposable)font1).Dispose();
    }
}
// You can do the same thing with a using statement. 
using (Font font2 = new Font("Arial", 10.0f))
{
    byte charset = font2.GdiCharSet;
}




     Refactoring

          Refactorings são saudáveis e devem ser feitos. Sempre que achar que um código pode ser melhorado quanto à legibilidade melhore-o. Sempre que algo pode ser feito de maneira mais rápida, mais fácil, mais elegante ou mais correta, refaça. Sempre que algo soar estranho, parecer "cheirar", troque. Use a regra do escoteiro e deixe o código mais limpo do que quando você encontrou.


     Gambiarras

          Toda gambiarra no código se volta contra você uma hora ou outra. Gambiarras causam infernos de manutenção, horas extras e expedientes de fim de semana.
          Toda gambiarra clama em alta voz por um refactoring. Um código ruim pode ter bad smells que são fruto de desconhecimento, limitações tecnológicas, cansaço ou erro humano, MAS gambiarras são sinais de relaxo, falta de ética e desorganização pessoal. O prazo não é desculpa para se fazer uma gambiarra. Se há uma forma mais elegante de se escrever um código procure melhorá-lo, mas se há uma forma definitivamente correta de se escrever um código, então use essa forma.


     Excessões à regra     

          Widgets demasiadamente usados como Button e Textbox tem padrões de nomenclatura derivados da notação húngara fortemente entrincheiradas em nosso dia - a - dia, por isso são aceitáveis coisas como botões precedidos de btn (btnSalvar) e inputs precedidos de txt (txtNome). Isso está em conformidade com as práticas da Microsoft, pois os widgets de tela do office são todos prefixados.    
          Variáveis de contadores de laço/iteradores podem ter um nome de uma letra só, como i,j,k,l,c. É mais inteligível desta forma, uma vez que os caracteriza como iteradores, além disso eles têm um escopo muito local, muito limitado.  
          Em linguagens onde o nome da classe não pode ser igual ao nome do arquivo que a contém é comum, em PascalCase, prefixar as classes com T, mas apenas nesses casos.  
          Em linguagens que não são case sensitive, como Delphi/Pascal/SQL, não é possível declarar um campo privado com camelCase e a propriedade que o acessa com o mesmo nome em PascalCase como abaixo:
 
//Nào faça isso
private string nome;
public string Nome
{
     get
     {
          return nome;
     }
    
     set
     {
          nome = value;
     }
} 
     Porém esse seria o nosso caso apenas usando SQL/Pascal/VB6. Usando C# isso não se aplica. Esse exemplo é trivial, mas o uso de _ ou de camelCase para os fields privados são os mais usados em C#.
     Nesses casos preceder o campo privado com F (PascalCase) em linguagens derivadas de pascal.

//isso só é permitido em linguagens como Pascal ou Delphi. Não faça isso.
private string Fnome;
public string Nome
{
     get
     {
          return Fnome;
     }
 
     set
     {
          Fnome = value;
     }
}

     Como usaremos apenas C#, vamos prefixar campos de instancia locais com _, como geralmente é feito em linguagens derivadas de C.

//Faça ISSO:
private string _nome;
public string Nome
{
     get
     {
          return _nome;
     }
 
     set
     {
          _nome = value;
     }
}


     Faça:



  • Use PascalCasing para nomear classes, propriedades, métodos e Enuns
  • Use camelCasing para nomear variáveis locais, argumentos de métodos e de constructors
  • Use _camelCasing (camelCase precedido de _) para nomear campos privados
  • Se uma apreviação for fazer parte do nome de uma classe, propriedade ou constante, use PascalCase se ela tiver 3 letras ou mais. Ponha a abreviação em maiúsculas se ela tiver até 2 letras.
  • Use os nomes de tipos predefinidos da linguagem em vez dos System Types, exemplo: strung no lugar de String, int no lugar de Int32, bool no lugar de Boolean
  • Use variáveis implícitas para quando o tipo é óbvio ou não é importante, ou em laços for/foreach. Exemplo: var numero = Convert.ToInt32(Console.ReadLine());
  • Escreva um comando por linha
  • Escreva uma declaração por linha
  • Indente todas as linhas de continuação
  • Quebre uma linha para separar a definição de métodos da definição de propriedades
  • Prefira passar estruturas ou objetos DTO como parâmetros para um método do que listas grandes de parâmetros.
  • Prefira retornar objetos DTO ou estruturas com um propósito específico do que usar parâmetros ref ou out nos seus métodos.
  • Sempre que usar o operador "as " para typecasting seguro verifique se o retorno não é null. Se for null é porque o objeto não pode ser convertido para o tipo especificado.
  • Se você precisa comentar um bloco de código, considere usar refactoring para transformar esse bloco em um método, e de-lhe um nome conciso e apropriado.        
  • Mantenha o tamanho de cada linha em até 130 caracteres (o suficiente para evitar rolagem horizontal)
  • Sempre envolva expressões booleanas de estrutura de repetição ou de decisão do tipo if, else, do, while, for e foreach com parênteses, mesmo que o compilador não exija.


       

     Não faça:



  • Não use notação húngara ou qualquer tipo de definição de tipo nos nomes de variáveis, isso é consistente com o .net framework, além disso o Visual Studio já te ajuda a determinar o tipo das variáveis.
  • Não use maiúsculas para nomear constantes, não é assim que é feito no .net. Maiúsculas atraem muito atenção.
  • Evite abreviações nos nomes de variáveis a não ser que sejam abreviações bem conhecidas como Id, XML, HTML
  • Não insira underscore _ no meio de identificadores, classes, constantes, propriedades e variáveis.
  • Não especifique o tipo de um enum a não ser que seja Flags ou bit fields
  • Não prefixe ou sufixe os nomes de Enum com a palavra "Enum"
  • Não comente código, ninguém saberá o que fazer com código comentado
  • Não use parâmetros de função como variáveis temporárias. O nome do parâmetro não reflete a intenção da variável.
  • Não use números em identificadores de campos ou métodos, como "Listar2". Isso geralmente é sinal de preguiça em encontrar um nome que revele propósito.
  • Não compare expressões booleanas com true ou false em if's. Perguntar if (variavel == true) ou if (variavel == false) prejudica a leitura e revela falta de conhecimento da estrutura if. Use if (variavel) ou if (!variavel).



     Lembre-se:

          A qualidade de um código é medida pelo número de "que diabos ..." por segundo.    
          A honestidade nas pequenas coisas não é uma coisa pequena.
   

Veja mais
Lance Hunt C# Coding Standards
AvSol coding guidelines for C# 3.0-5.0
Java code conventions


Livros
http://www.livrariacultura.com.br/p/domain-driven-design-3252884
http://www.livrariacultura.com.br/p/extreme-programming-15065191
http://www.livrariacultura.com.br/p/codigo-limpo-2874223


Sites
http://www.milfont.org/tech/2008/01/21/nao-use-notacao-estranha/
http://www.macoratti.net/13/09/net_pcod1.htm


Outras fontes
     Há vários padrões de codificação e outras boas práticas de programação. Abaixo exemplifico mais algumas fontes como referência / aprofundamento.
     Há também padrões de codificação para linguagens específicas, elaborados pelas empresas que desenvolvem esses produtos ou pela comunidade de programadores destas linguagens, como os padrões de PHP ou Java exemplificados em anexo.
http://www.dofactory.com/reference/csharp-coding-standards
https://csharpguidelines.codeplex.com/
http://se.inf.ethz.ch/old/teaching/ss2007/251-0290-00/project/CSharpCodingStandards.pdf
https://msdn.microsoft.com/en-us/library/vstudio/ms229043(v=vs.100).aspx




 

Comentários

  1. Ótimo post.
    Será de grande ajuda nos meus estudos.
    No momento estou iniciando o C# no curso adv, www.cursoadv.com.br
    Essa matéria me ajudará muito a ser mais produtivo .

    ResponderExcluir

Postar um comentário

Postagens mais visitadas deste blog

Uso de memória no SQL Server

Busca de CEP com o Lazarus - Parte 1 - UrlEncode

Botão Add This para adicionar seu post em qualquer rede