C# 9.0 - Top  Level Statements


 Hoje vamos apresentar o novo recurso do C# 9.0 chamado Top-Level Statements, ou, Instruções de nível superior, que simplifica a criação de classes.

Quando você cria um projeto Console usando as versões anteriores do C# você vai obter por padrão o seguinte template de código :

São doze linhas de código (tudo bem uma esta em branco) mas mesmo assim é um tanto verboso para uma simples aplicação que vai apenas escrever 'Hello World' no console.

Se você estiver iniciando o aprendizado com o C# este programa vai confrontá-lo com um monte de conceitos como:

Muita coisa para um iniciante não é mesmo ????

Mas com o C# 9.0 que acompanha o .NET 5.0 isso mudou.

Importante:  Para usar o C# 9.0 e conferir este recurso  você precisa instalar o .NET 5.0 RC1 e o Visual Studio 2019 Preview.  O arquivo de projeto .csproj deve possuir a seguinte definição:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>  
    <OutputType>Exe</OutputType>
         <TargetFramework>net5.0</TargetFramework>
        <LangVersion>9.0</LangVersion>

  </PropertyGroup>

</Project>

Com o C# 9.0 agora você pode escrever instruções diretamente no nível superior de um arquivo sem a necessidade de definir uma classe e um método Main estático.

Veja como fica o mesmo código criado para uma aplicação Console padrão :

Apenas 3 linhas de código onde estamos usando os seguintes recursos:

Assim fica muito mais fácil para quem esta começando com o C#, o código fica mais enxuto e mais fácil de ler.

E podemos ter um código conforme abaixo:

Que quando executado fornece o resultado abaixo:

Vamos agora incluir uma classe Teste no projeto com e alterar o seu código conforme abaixo:

Note que temos uma mensagem de erro :  Only one compilation unit can have top-level statements.

O que esta acontecendo aqui ?

A mensagem indica que podemos ter somente uma unidade de compilação com instrução de nível superior.

Porque ?

Para desvendar o mistério vamos recorrer ao utilitário ildasm.exe ou seja o disassembler IL que pega um arquivo executável portátil (PE) que contém código de linguagem intermediária (IL) e cria um arquivo de texto adequado como entrada para Ilasm.exe.

Para executá-lo localiza a pasta onde instalou o VS 2019 no menu iniciar do Windows e acione execute o programa: Developer Command Prompt for Visual Studio 2019 :

Será aberta uma janela de prompt de comando do desenvolvedor.

Nesta janela digite ildasm e tecle Enter:

Será aberto o Intermediate Language Disassembler:

Usando o Intermediate Language Disassembler, vamos abrir o arquivo ConsoleApp.dll de nosso aplicativo console que usa o recurso de programa de nível superior do C# 9.

Abaixo temos o resultado da abertura do arquivo .dll :

Você pode ver que temos uma classe $Program e um método $Main estático gerados nos bastidores para nós.

Isso significa que ainda há um método Main estático, mas ele é gerado automaticamente se você criar um programa de nível superior onde não define esse método principal explicitamente em seu código.

Clicando duas vezes sobre o método $Main  você pode ver o Intermediate Language Code abaixo:

Observe que temos a instrução Console.WriteLine de nível superior adicionada a esse método $Main gerado, ou seja ,  todas as suas instruções de nível superior são adicionadas ao método $Main gerado.

Assim continuamos tendo apenas um ponto de entrada da aplicação definido pelo método Main(), e se você tentar incluir outra instrução de nível superior o compilador não vai permitir.

Dessa forma para um arquivo com instruções de nível superior, um método $Main é gerado e definido como ponto de entrada. Como pode haver apenas um ponto de entrada para seu aplicativo .NET, só pode haver exatamente um arquivo em seu projeto que tenha instruções de nível superior.

Outro ponto importante a destacar é que quando você declara namespaces e/ou tipos em seu arquivo de programa de nível superior, essas declarações devem vir após todas as instruções de nível superior, caso contrário, você receberá um erro de compilação.

Como exemplo veja o trecho de código a seguir onde definimos a classe Teste com a propriedade Nome antes das instruções de nível superior:

Observe a mensagem de erro:  Top-Level statements must precede namespace and type declarations.

A ordem correta para declarar o tipo Teste é mostrado abaixo:

Dessa forma o novo recurso instruções de nível superior é ótimo para realizar testes e quando seu projeto é bem simples. Você não precisa incluir namespaces, class nem o método Main().

Embora o código inicial seja bem resumido isso pode dificultar o entendimento do que esta realmente acontecendo para quem esta iniciando com a linguagem.

Referências:


José Carlos Macoratti