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

Asked

Viewed 424 times

10

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

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

However, C# allows me to use command blocks to create scopes without being for the above situations, i.e., 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 above example I used for illustration to a block that contains an integer type variable valor2, i wonder what is the purpose of a command block like this? And yet the compiler allowed me to create an empty block { }, compiler did not report any error corresponding to this empty block, does it have any utility in using an empty block? Since it is allowed by the compiler.

2 answers

9


As you can see, the definition of what a command block is already wrong. It allows zero or more commands (I don’t really like the translation of statement for command, but she the closest we have, so acceptable if one understands well what this means).

Empty method

If it’s a method that should do nothing inside, there:

public void Exemplo() {}

This is a method that explicitly must do nothing. It is rare to have such a need, but it has its usefulness. It is more common in virtual methods. Either the virtual must do nothing, but lets its descendants do or what it overwrites must eliminate the behavior of the ascendant. If the option is this then it should be very well thought out.

Note that an empty method is different from a virtual or partial method without implementation. The empty one has an implementation, which is to do nothing. And if it’s a mistake to call that method that you were forced to implement by some contract, you should first think about whether you should use that contract, and second choose to make an exception (NotImplementedException) not to use it instead of swallowing the execution. Purists will say that you should not use the second option, pragmatists will say that it is not so serious to do this, even more so if you have some tool that helps detect this before going to the Runtime.

Empty block

In fact using the empty block in this way is of no use. But why should it give an error?

Remembering that the compiler doesn’t try to be smarter than he needs. It would take a lot of work to keep checking something that doesn’t make a difference. The compiler has more important things to do. Besides this the most it could give is a Warning, after all makes no mistake to do this. Still it would be an exaggeration, because even warnings should be for cases where it has real potential to cause problems. Which leads to say that many programmers do not treat warnings as errors, though they are, and will cause problems. I have already picked up a legacy code of 120,000 lines that owned 600,000 warnings. And the code "worked" :D At most this should be the object of static analysis where false positives are expected.

New scope

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

In general the code can be modified to prevent this, but it is also not so necessary. Often when this is necessary it means that 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;
    }
}

I put in the Github for future reference.

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

As a matter of fact, 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 think it is important. I see so much that is more important and does not exist in language.

  • I took the definition of a book I have here about C#rs

5

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.