C#  -  Novidades da versão 7 - I


 Neste artigo vou apresentar as novidades da versão 7.x da linguagem C#.

A versão 6.0 da linguagem C# trouxe novidades como:
  • static using
  • métodos e propriedades expression-bodied
  • inicializadores de propriedades auto-implementadas
  • auto propriedades read-only
  • o operador nameof
  • o operador null condicional
  • os inicializadores de dicionário
  • e await no bloco try/catch

Pois bem, o que temos de novo para a versão 7.x do C# ?

Um artigo abordando em detalhes cada novidade ficaria muito extenso.

Assim vou apresentar, de forma bem resumida cada novidade, e, mesmo assim vou dividir o assunto em duas partes.

A leitura incorreta de constantes numéricas pode dificultar a compreensão do código ao lê-lo pela primeira vez. Máscaras de bits ou outros valores simbólicos são propensos a mal-entendidos.

O C# 7.0 inclui dois novos recursos para escrever números da maneira mais legível para o uso pretendido:

  1. Separadores de dígitos.
  2. Literais binários 

Separadores de Dígitos

Freqüentemente, ao desconstruir uma tupla ou chamar um método sem parâmetros, você é forçado a definir uma variável cujo valor você não se importa e não pretende usar.

Um descarte é uma variável somente gravação cujo nome é _ (caractere sublinhado); você pode atribuir todos os valores que pretende descartar à única variável. Um descarte é como uma variável não atribuída; além da declaração de atribuição, o descarte não pode ser usado no código.

Os descartes tornam o código mais legível. Você pode adicionar _ a números separados ao declarar variáveis. O compilador apenas remove o _.

Exemplo a seguir vemos que a leitura fica mais legível :


 long n1 = 0x1234567890ABCDEF;
 

 long n2 = 0x1234_5678_90AB_CDEF;

 

 

long n2 = 0x_1234_5678_90AB_CDEF;
 

C# 6.0 C# 7.0 C# 7.2

Na versão 7.2 do C# podemos usar o separador _  no início do número.

Literais binários

O C# 7 oferece um novo literal para binários. Os binários podem ter apenas os valores 0 e 1. Agora, o separador de dígitos ( _ ) torna-se especialmente importante:


uint binario1 = 0b1111_0000_1010_0101_1111_0000_1010_0101;

 
C# 7.0

Membros de Expression-bodied

Na versão 6.0 do C# podemos ter métodos e propriedades no corpo de expressões ou expression-bodied.

Na versão 7 do C# , os corpos de expressão podem ser usados com construtores, destrutores, funções locais, acessadores de propriedades e muito mais.

Aqui você pode ver a diferença com acessores de propriedade entre o C# 6 e o C# 7:

private string _nome;
public string Nome
{
   get { return _nome; }
   set { Set(ref _nome, value); }
}
 
private string _nome;
public string Nome
{
  get => _firstName;
  set => Set(ref _nome, value);
}
C# 6.0 C# 7.0

Variável out

A sintaxe existente que suporta os parâmetros out foi aprimorada nesta versão. Agora você pode declarar variáveis na lista de argumentos de uma chamada de método, em vez de escrever uma declaração de declaração separada.

Antes do C# 7, as variáveis out (ou de saída) tinham que ser declaradas antes de seu uso.

Com C# 7, o código é reduzido por uma linha porque a variável pode ser declarada em uso:

string n = "42";
int resultado;

if (string.TryParse(n, out resultado)
{
    Console.WriteLine($"Conversão feita com sucesso: {resultado}");

}

 
 

string n = "42";

if (string.TryParse(n, out var resultado)
{
  Console.WriteLine($"Conversão feita com sucesso: {resultado}");
}

C# 6.0 C# 7.0

Argumentos non-trailing

Nas versões anteriores do C#, nós tínhamos duas maneiras de usar argumentos nomeados.

Podemos especificar todos os nomes de argumentos e deixar de fora aqueles com valor padrão ou nós especificamos argumentos posicionais primeiro e depois argumentos nomeados.

v = Volume(a: 3, c: 5, b: 4);
v = Volume(3, b: 4, c: 5);

v = Volume(3, b: 4, 5);
C# 6.0 C# 7.2

Com o C# 7.2, agora é permitido ter argumentos nomeados também após os posicionados. Esse recurso é chamado de argumentos nomeados sem rastreio.

Struct readonly

Estruturas devem ser somente leitura (com algumas exceções). Usando o C # 7.2, é possível declarar uma estrutura com o modificador readonly, portanto, o compilador verifica se a estrutura não foi alterada.

Esta garantia pode também pode ser usada pelo compilador para não copiar uma estrutura que a transmita como um parâmetro, mas em vez disso a passa como um parâmetro de referência:

public readonly struct Dimensoes
{
   public double Comprimento { get; }
   public double Largura { get; }
   public Dimensoes(
double comprimento, double largura)
   {
      Comprimento = comprimento;
      Largura = largura;
    }

    public double Diagonal => Math.Sqrt(Comprimento * Comprimento + Largura * Largura );
}

C# 7.0

Parâmetros In

No C# 7.2 podemos usar o modificador in com parâmetros, alem de ref e out. Isso garante que um tipo de valor passado não seja alterado, e ele pode ser passado por referência para evitar uma cópia:

static void Calcular(in int numero)
{
   
// o valor numero não pode ser alterado
}
 
C# 7.0

Private protected

O C# 7.2 incluiu um novo nível de acessibilidade: private protected. Isso é para coincidir com o mesmo nível de acesso que já existe no CLR.

O membro declarado com essa acessibilidade pode ser visível nos tipos derivados desse tipo de contenção dentro do assembly.

Não é visível para qualquer tipo não derivado do tipo de contenção ou fora do assembly que o contém. isto é, o acesso é limitado a tipos derivados dentro do conjunto de contenção.

Isso é muito útil se os desenvolvedores quiserem implementar algo visível apenas para o nível de assembly interno.

  public class Base
  {
      protected private void M()
      {
        Console.WriteLine("Origem Base.M()");
      }
  }

  public class Derivada : Base
  {
     new public void M()
     {
         Console.WriteLine("Origem Derivada.M()");
         base.M();
     }
}
C# 7.0

Target-Type Default

No C# 7.1, temos agora definido um literal padrão que permite uma sintaxe mais curta em comparação com o operador padrão.

O operador padrão sempre requer a repetição do tipo, que agora não é mais necessário, oque facilita para tipos complexos.

int x = default(int);
ArrayImutavel<int> arr = default(ArrayImutavel<int>);
int x = default;
ArrayImutavel<int> arr = default;
C# 7.0 C# 7.1

Funções Locais

Antes de C# 7, não era possível declarar uma função dentro de um método. Você poderia criar um expressão lambda e invocá-la como mostrado aqui no trecho de código C# 6:

public void Calcular()
{
     Func<int, int, int> Somar = (x, y) => x + y;
     int resultado = Somar(38, 4);
     Console.WriteLine(resultado);
}
C# 6.0

Com C# 7, uma função local pode ser declarada dentro de um método.

A função local só é acessível dentro do escopo do método:

public void Calcular()
{
    int Somar(int x, int y) => x + y;
    int resultado = Somar(38, 4);
    Console.WriteLine(resultado);
}
C# 7.0

Na segunda parte do artigo vou concluir a apresentação das novidades do C# 7.x.

"Porque Cristo não entrou num santuário feito por mãos, figura do verdadeiro, porém no mesmo céu, para agora comparecer por nós perante a face de Deus;"
Hebreus 9:24

 

 

Referências:


José Carlos Macoratti