What is the purpose of empty command blocks or which do not belong to any command?

10

A command block is made up of two or more commands in {...//Comandos} keys, I can use them for the following situations I already know:

  • In an if: if(codicao){...//Comandos} .
  • In a for: for(inicializacao; condicao; incremento){...//Comandos} .
  • In a while: while(codicao){...//Comandos} .
  • In functions: void fazAlgo(){...//Comandos} .
  • And also classes and other language commands.

However, C # allows me to use command blocks to create scopes without being to the above situations, ie a block of commands that do not belong to any of the traditional commands mentioned above.

See the example created to illustrate the situation:

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();
}

In the example above that I used for illustration to a block that contains an integer variable valor2 , I would like to know what is the purpose of a block of commands like this? And still the compiler allowed me to create an empty block { } , the compiler did not acknowledge any error corresponding to this empty block, have any use in using an empty block? Since it is allowed by the compiler.

    
asked by anonymous 22.01.2016 / 02:37

2 answers

9

As you can see the definition of what a command block is already wrong. It allows zero or more commands (I do not much like the translation of statement for command, but it's the closest we have, so acceptable if the person understands well what this means ).

Empty Method

If it is a method that should do nothing, there it is.

public void Exemplo() {}

This is a method that should explicitly do nothing. It is rare to have such a need, but it has its usefulness. It is most common in virtual methods. Either the virtual should do nothing but let their offspring do or what they override should eliminate the behavior of the ascendant. If the option is is should be very well thought out.

Note that an empty method is different from a non-implementation virtual or partial method. The void has an implementation, which is doing nothing. And if it is a mistake to call that method that you were forced to implement by some contract, you should first use that contract, and secondly you have to throw an exception ( NotImplementedException ) not to use it instead of swallowing it. execution. The purists who should not use the second option, the pragmatists will say that it is not so serious to do this, especially if you have some tool that will help you detect this before going to the runtime .

Empty block

In fact using the empty block in this way is useless. But why should I make a mistake?

Remembering that the compiler does not try to be smarter than it needs to. It would take a lot of work to keep checking something that does not make any difference. The compiler has more important things to do. In addition, the most you could give is a warning , after all it does not cause any error to do this. Even so, it would be an exaggeration, because even warnings should be for cases where it has real potential to cause problems. Which goes to say that many programmers do not treat warnings as errors, although they are and will cause problems. I've already got a legacy code of 120,000 lines that has 600,000 warnings . And the code "worked": D At most this should be subject to static analysis where false positives are expected.

New scope

The case of the block without being bound to the command is useful in cases where you need to enter a variable and the same name, so it becomes readable, where another variable with the same name already exists.

In general the code can be modified to avoid this. But it's not so necessary either. Many times when this is needed it means the method is too complicated.

These two variables have the same name but are completely independent.

{
    {
        int x = 0;
    }

    {
        int x = 0;
    }
}

This is valid. The below does not compile because the variable of one scope may be hiding the other:

{
    {
        int x = 0;
    }
    int x = 0;
}

It would make more sense in cases like this:

{
    if (true) { //aqui iria uma condição real
        int x = 0;
    }

    {
        int x = 0;
    }
}

Without the seemingly unnecessary block this would not compile. The first x could be "shadowing" the second. With the block, they become independent and compile.

To tell you the truth, the usefulness of this is quite theoretical. In practice it is possible to produce readable code without having to worry about it. In this particular case, if this block did not exist, it would not be much missed. Of course, some people think it's important. I see so much that is more important and does not exist in language.

    
22.01.2016 / 10:25
5

No, there is no use in using the block {} empty, it is simply ignored by the compiler, the utility is only used when it is being used next to another command being: if , else while , etc. But alone it is only ignored in the same way that begin / end is used together with if , else , while in Delphi. If you create a begin / end empty the Delphi compiler will also compile normally as in C # because it just ignored the empty block. I hope I have helped.

    
22.01.2016 / 06:07