Stack Overflow em Português Asked by gato on January 11, 2021
Um bloco de comandos é composto de dois ou mais comandos entre chaves {...//Comandos}
, eu posso usar eles para as seguintes situações que já conheço:
if(codicao){...//Comandos}
.for(inicializacao; condicao; incremento){...//Comandos}
.while(codicao){...//Comandos}
.void fazAlgo(){...//Comandos}
.No entanto, o C# permite que eu use blocos de comandos para criar escopos sem que seja para as situações acima, ou seja, um bloco de comandos que não pertencem a nenhum dos comandos tradicionais citados acima.
Veja o exemplo criado para ilustrar a situação:
static void Main(string[] args)
{
int valor1 = 50;
{ //Inicio do bloco
int valor2 = 100;
Console.WriteLine("valor1 no bloco: " + valor1);
Console.WriteLine("valor2 no bloco: " + valor2);
} //Fim do bloco
//Bloco vazio.
{ }
Console.WriteLine("valor1 fora bloco: " + valor1);
Console.ReadKey();
}
No exemplo acima que utilizei para ilustração a um bloco que contem uma variável de tipo inteiro valor2
, eu gostaria de saber qual é a finalidade de um bloco de comandos como este? E ainda o compilador me permitiu criar um bloco vazio { }
, o compilador não acusou nenhum erro correspondente a este bloco vazio, tem alguma utilidade em usar um bloco vazio? Já que ele é permitido pelo compilador.
Como já deu para perceber, a definição do que é um bloco de comando já está errada. Ele permite zero ou mais comandos (não gosto muito da tradução de statement para comando, mas ela a mais próxima que temos, então aceitável se a pessoa entender bem o que isto significa).
Se for um método que deve fazer nada dentro, aí tem:
public void Exemplo() {}
Este é um método que explicitamente deve fazer nada. É raro ter uma necessidade assim, mas tem sua utilidade. É mais comum em métodos virtuais. Ou o virtual deve fazer nada, mas deixa seus descendentes fazerem ou o que sobrescreve deve eliminar o comportamento do ascendente. Se a opção for esta então deve ser muito bem pensada.
Note que um método vazio é diferente de um método virtual ou parcial sem implementação. O vazio tem uma implementação, que é fazer nada. E se é um erro chamar aquele método que foi obrigado a implementar por algum contrato, deve em primeira opção pensar se deveria usar aquele contrato, e em segunda optar por lançar uma exceção (NotImplementedException
) para não usá-lo em vez de engolir a execução. Os puristas dirão que não deve usar a segunda opção, os pragmáticos dirão que não é tão grave fazer isto, ainda mais se tiver alguma ferramenta que ajude detectar isto antes de ir para o runtime.
De fato usar o bloco vazio desta forma não tem utilidade. Mas por que deveria dar um erro?
Lembrando que o compilador não tenta ser mais esperto do que ele precisa. Daria muito trabalho para ficar verificando algo que não faz diferença. O compilador tem coisas mais importantes para fazer. Além disto o máximo que poderia dar é um warning, afinal não causa erro algum fazer isto. Mesmo assim seria um exagero, porque mesmo warnings devem ser para casos onde tem potencial real para causar problemas. O que leva a dizer que muitos programadores não tratam warnings como erros, embora eles sejam, e vão causar problemas. Eu já peguei um código legado de 120 mil linhas que possuía 600 mil warnings. E o código "funcionava" :D No máximo isto deveria ser objeto de análise estática onde os falsos positivos são esperados.
O caso do bloco sem estar vinculado ao comando é útil em casos onde precisa introduzir uma variável e mesmo nome, assim fica legível onde já existe outra variável com mesmo nome.
Em geral o código pode ser modificado para evitar isto, mas também não é tão necessário. Muitas vezes quando isto é necessário significa que o método está complicado demais.
Estas duas variáveis possuem o mesmo nome mas são completamente independentes.
{
{
int x = 0;
}
{
int x = 0;
}
}
Isto é válido. Já o abaixo não compila porque a variável de um escopo pode estar escondendo a outra:
{
{
int x = 0;
}
int x = 0;
}
Faria mais sentido em casos assim:
{
if (true) { //aqui iria uma condição real
int x = 0;
}
{
int x = 0;
}
}
Coloquei no GitHub para referência futura.
Sem o bloco aparentemente desnecessário isto não compilaria. O primeiro x
poderia estar "sombreando" o segundo. Com o bloco eles se tornam independentes e compila.
Pra falar a verdade, a utilidade disto é algo bastante teórica. Na prática é possível produzir código legível sem ter que se preocupar com isto. Neste caso específico se não existisse este bloco não faria grande falta. Claro que alguns acham que é importante. Vejo tanta coisa que é mais importante e não existe na linguagem.
Correct answer by Maniero on January 11, 2021
Não, não há nenhuma utilidade em usar o bloco {}
vazio, ele simplesmente é ignorado pelo compilador, a utilidade dele se dá apenas quando está sendo usado junto a outro comando sendo eles: if
, else
,while
, etc. Mas sozinho é apenas ignorado da mesma forma que o begin
/end
é utilizado junto ao if
, else
, while
no Delphi. Se você criar um begin
/end
vazio o compilador Delphi também irá compilar normalmente como em C#, pois apenas ignorou o bloco vazio. Espero ter ajudado.
Answered by Viniam on January 11, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP