.NET

16 jan, 2018

Novidades do C# 7.2 – Parte 01: como habilitar, ref readonly e in parameters

Publicidade

Neste primeiro artigo, inicio uma série sobre os recursos que integram o C# 7.2.

Esta nova versão da linguagem C# foi lançada de maneira oficial juntamente com o Update 15.5 do Visual Studio 2017. Para maiores detalhes a respeito dessa atualização acesse este link.

Habilitando o uso do C# 7.2 no Visual Studio 2017

Os exemplos apresentados neste artigo foram implementados a partir do Visual Studio 2017 Update 15.5. É importante ressaltar que releases anteriores não contam com suporte para a versão 7.2 da linguagem C#.

Caso o uso do C# 7.2 não tenha sido previamente habilitado, um alerta aparecerá no Visual Studio 2017 ao tentar empregar algum dos novos recursos:

A fim de evitar este tipo de problema, será necessário alterar as propriedades do projeto em questão. Na seção Build, acionar a opção Advanced:

Aparecerá neste momento a janela Advanced Build Settings, com a opção C# latest major version (default) selecionada:

Em Language version, selecionar então C# 7.2 ou C# latest minor version (latest), a fim de habilitar os recursos da nova versão da linguagem:

ref readonly returns

A possibilidade de retornar um valor por referência em um método existe desde a versão 7.0 da linguagem C#. Para saber mais a respeito, consulte este artigo: C# 7.0: Ref Returns.

Tal capacidade permite, no entanto, que se modifique o conteúdo de uma referência fora do local em que a mesma foi declarada. Em alguns casos, este comportamento pode resultar em efeitos indesejáveis.

Com o C# 7.2 é possível marcar o retorno de um método com as palavras-chaves ref e readonly, garantindo, assim, que a referência retornada não sofra modificações. O método ObterContador no tipo ClasseExemplo demonstra o uso deste novo recurso:

namespace ExemploRefReadonly
{
    public class ClasseExemplo
    {
        private int _contador = 0;

        public void Incrementar()
        {
            _contador++;
        }

        public int ObterValorContador()
        {
            return _contador;
        }

        public ref readonly int ObterContador()
        {
            return ref _contador;
        }
    }
}

Na listagem a seguir, é possível observar exemplos de utilização do método ObterContador do tipo ClasseExemplo, com a variável que receberá seu retorno estando marcada com ref readonly:

using System;

namespace ExemploRefReadonly
{
    class Program
    {
        static void Main(string[] args)
        {
            ClasseExemplo exemplo = new ClasseExemplo();
            ref readonly int teste = ref exemplo.ObterContador();
            Console.WriteLine(teste);

            exemplo.Incrementar();
            Console.WriteLine(teste);

            exemplo.Incrementar();
            Console.WriteLine(teste);

            Console.ReadKey();
        }
    }
}

A próxima imagem traz o resultado da execução deste código:

in parameters

Além da passagem de parâmetros por referência utilizando ref e out (alternativas existentes desde as primeiras versões), o C# 7.2 adicionou uma terceira possibilidade: a palavra-chave in.

Este novo recurso permite que parâmetros funcionem como referências somente leitura, impedindo assim a modificação de valores em um método que dependa dessa funcionalidade.

A tentativa de atribuir um valor a uma variável associada à palavra-chave in resultará em um erro (diferentemente de declarações que empreguem ref), como indicado na imagem a seguir:

A próxima listagem traz um exemplo de uso da palavra-chave in na declaração de uma referência somente leitura:

namespace ExemploIn
{
    public static class Fatorial
    {
        public static int Calcular(in int numero)
        {
            int resultado = 1;
            for (int i = numero; i > 1; i--)
                resultado *= i;

            return resultado;
        }
    }
}

Diferentemente de ref, não será obrigatório empregar a palavra-chave in em um método que receba referências somente leitura. Constantes e expressões também podem ser utilizadas em parâmetros definidos com in. A listagem a seguir exemplifica estes diversos aspectos, com diferentes tipos de chamadas ao método estático Calcular da classe Fatorial:

using System;

namespace ExemploIn
{
    class Program
    {
        static void Main(string[] args)
        {
            int numero;

            numero = 0;
            Console.WriteLine(
                quot;{numero}! = {Fatorial.Calcular(numero)}");

            numero = 1;
            Console.WriteLine(
                quot;{numero}! = {Fatorial.Calcular(numero)}");

            Console.WriteLine(
                quot;2! = {Fatorial.Calcular(1 + 1)}");

            numero = 3;
            Console.WriteLine(
                quot;{numero}! = {Fatorial.Calcular(in numero)}");

            numero = 4;
            Console.WriteLine(
                quot;{numero}! = {Fatorial.Calcular(in numero)}");

            Console.WriteLine(
                quot;5! = {Fatorial.Calcular(5)}");

            Console.ReadKey();
        }
    }
}

Na próxima imagem está o resultado da execução desta aplicação de testes:

Referências