Passei a maior parte dos últimos anos trabalhando principalmente com C # e SQL. Todo programador com quem trabalhei durante esse tempo costumava colocar a chave de abertura de uma instrução de fluxo de controle ou função em uma nova linha. Assim ...
public void MyFunction(string myArgument)
{
//do stuff
}
if(myBoolean == true)
{
//do something
}
else
{
//do something else
}
Sempre fiquei impressionado com o desperdício de espaço, especialmente nas declarações if / else. E eu sei que existem alternativas nas versões posteriores do C #, como:
if(myBoolean == true)
//do something on one line of code
Mas quase ninguém os usou. Todo mundo fez o negócio de usar cacheados na nova linha.
Então voltei a fazer JavaScript após uma longa ausência. Na minha memória, os desenvolvedores de JavaScript costumavam fazer exatamente a mesma coisa, mas com todas as novas e sofisticadas bibliotecas e outras coisas, a maioria dos desenvolvedores coloca a chave de abertura após a declaração:
function MyJavaScriptFunction() {
//do something
}
Você pode ver o sentido disso, porque como o uso de fechamentos e ponteiros de função se tornou popular em JavaScript, ele economiza muito espaço e torna as coisas mais legíveis. Então, eu me perguntava por que não era visto como algo feito em C #. De fato, se você tentar a construção acima no Visual Studio 2013, ela realmente a reformará para você, colocando a chave de abertura em uma nova linha!
Agora, acabei de ver esta pergunta na Code Review SE: https://codereview.stackexchange.com/questions/48035/questions-responses-let-me-tell-you-about-you. Em que aprendi isso em Java, um idioma com o qual eu não estou muito familiarizado, é considerado pouco rigoroso abrir o aparelho logo após a declaração, da maneira moderna do JavaScript.
Eu sempre entendi que o C # era originalmente modelado após o Java e mantinha muitos dos mesmos padrões de codificação basal. Mas, neste caso, parece que não. Então, presumo que deve haver uma boa razão: qual é a razão? Por que os desenvolvedores de C # (e o Visual Studio) impõem a abertura de colchetes em uma nova linha?
fonte
if(myBoolean == true)
faz pouco sentido para mim. Enquanto estamos nisso, enquanto nãoif ((myBoolean == true) == true)
? Apenasif (myBoolean)
e isso é o suficiente. Desculpe, uma irritação minha.Respostas:
A chave no final da linha é o antigo padrão K&R C, de Brian Kernighan e Dennis Ritchie, o livro The C Programming Language , que eles publicaram em 1978 após co-inventar o sistema operacional UNIX e a linguagem de programação C (acho que C era projetado principalmente por Ritchie), na AT&T.
Costumava haver guerras de chamas sobre "o único estilo de chave".
Ritchie inventou a linguagem C e Kernighan escreveu o primeiro tutorial, quando as telas do computador mostravam apenas algumas linhas de texto. De fato, o desenvolvimento do UNICS (mais tarde UNIX) começou em um DEC PDP-7, que usava uma máquina de escrever, impressora e fita de papel para uma interface do usuário. O UNIX e C foram finalizados no PDP-11, com terminais de texto de 24 linhas. Portanto, o espaço vertical era de fato um prêmio. Hoje, todos nós temos telas um pouco melhores e impressoras de alta resolução, certo? Quero dizer, eu não sei sobre você, mas tenho três (3) telas de 24 "1080p à minha frente agora. :-)
Além disso, grande parte desse livrinho, The C Programming Language, é um exemplo de código que, ao colocar as chaves no final das linhas, em vez de em suas próprias linhas, economizava uma quantia considerável em impressão.
O que é realmente importante é a consistência em todo o projeto, ou pelo menos em um determinado arquivo de código-fonte.
Também existem estudos científicos que mostram que o suporte em sua própria linha (recuado no mesmo nível do código) melhora a compreensão do código, apesar do que as pessoas pensam que pensam da estética. Isso deixa muito claro para o leitor, visual e instintivamente, qual código é executado em que contexto.
O C # sempre apoiou a avaliação de um único comando após uma expressão de ramificação, a propósito. De fato, é a única coisa que faz, mesmo agora. Colocar o código entre chaves depois de uma expressão de ramificação apenas faz com que um comando saia (o compilador cria escopo usando instruções jmp). C ++, Java, C # e JavaScript são mais ou menos baseados em C, com as mesmas regras de análise subjacentes, na maior parte. Portanto, nesse sentido, o C # não é "baseado em Java".
Resumindo, isso é um pouco de uma questão religiosa / guerra de chamas. Mas não são estudos tornando-se bastante claro que organizar o código em blocos de melhora humana compreensão. O compilador não se importava. Mas isso também está relacionado à razão pela qual eu nunca coloquei uma linha de código depois de uma ramificação sem chaves - é muito fácil para mim ou outro programador inserir outra linha de código mais tarde e escorregar no fato de que não execute no mesmo contexto com a linha antes ou depois dela.
EDIT : Basta olhar o bug da Apple
goto fail
para obter um exemplo perfeito desse problema exato, que teve consequências muito graves no mundo real.torna-se...
Nesse caso, é
doSomethingElse()
executado sempre, independentemente do resultado do teste, mas como é recuado para o mesmo nível dadoSomething()
instrução, é fácil perder. Isso não é realmente discutível; estudos confirmam isso. Esta é uma grande fonte de erros introduzidos no código-fonte durante a manutenção.Ainda assim, admito que a sintaxe de fechamento do JavaScript parece um pouco boba com chaves em suas próprias linhas ... esteticamente. :-)
fonte
begin
eend
no lugar de chaves, o que dificulta a falta desses erros, além de ser mais rigoroso quanto à colocação de ponto-e-vírgula - mas gastar 4 dias no ano passado, depurando um problema no C incorporado, que acabou sendo devido à falta de colocação de chaves de alguém ..... Acho que deveria haver uma opção de compilador que torna as chaves obrigatórias para instruções de controle!A razão pela qual os desenvolvedores de C # fazem isso é porque é a configuração padrão do formatador automático do Visual Studio. Embora essa configuração possa ser alterada, a maioria das pessoas não, e, portanto, todos os desenvolvedores de uma equipe precisam ir com a maioria.
Por que esse é o padrão no Visual Studio, eu não sei.
fonte
Como eu hipotetizei nesta resposta aqui - https://softwareengineering.stackexchange.com/a/159081/29029 - Suponho que a decisão de usar o suporte de Allman possa ser um sinal da herança Pascal, já que Hejlsberg criou o Delphi antes de projetar o C # . O mesmo que Pascal para nomes de métodos.
Pessoalmente, acredito em seguir o ditado "em Roma, como os romanos". Eu uso Allman em C #, mas K&R em Java. Estou tão acostumado a isso que mudar a convenção de qualquer maneira é chocante para mim.
Acredito que alguma diversidade de convenções é realmente benéfica para um desenvolvedor "multilíngue", pois ajuda a lembrar em qual idioma eles estão codificando no momento e facilita a diferenciação de vários hábitos. É um equivalente mental da memória muscular, por assim dizer.
fonte
goto fail
, usar o recuo para controlar o fluxo do programa é o que os humanos naturalmente querem fazer; portanto, o que você vê é o que é executado. Se estiver indentado errado, simplesmente não funciona. Ter que decodificar o que esses aparelhos significam, se eles realmente refletem o recuo, é um trabalho adicional além da compreensão do programa. O recuo é redundante para chaves, então por que os programadores a usam se as chaves são úteis? O aninhamento profundo é ininteligível em qualquer idioma. Só estou dizendo.A convenção que você associa ao Java é o estilo K&R, ou "Um estilo de chave verdadeira", e vem originalmente de C. Esta página no estilo de recuo do venerável arquivo Jargon mostra a idade da distinção.
Eu sempre pensei que o estilo Allman e suas variantes são um reflexo de como os autores pensam sobre o código, elevando os delimitadores de bloco ao nível de palavras-chave semelhantes a como algumas linguagens usam "begin" e "end" em torno de blocos de código.
fonte