André Alves de Lima

Talking about Software Development and more…

Novidades do C# vNext – Primary Constructors

Olá caro(a) leitor(a)!

No post de hoje quero dar continuidade à pequena série sobre as novidades da próxima versão do C#. A propósito, antes de continuar a leitura, caso ainda não tenham conferido, vejam o artigo anterior, no qual eu demonstrei a funcionalidade chamada “Declaration Expressions, que já está implementada no C# vNext. Como mencionei no artigo anterior, essas novas funcionalidades foram anunciadas no evento Microsoft Build 2014, que foi realizado algumas semanas atrás.

A novidade que eu gostaria de apresentar hoje são os “Primary Constructors“. Essa funcionalidade permite que os parâmetros do construtor de uma classe sejam definidos diretamente na sua declaração. Esses parâmetros ficam então disponíveis em todo o contexto de inicialização da classe (construtores, inicialização de variáveis, etc). Nada melhor do que um exemplo para entendermos como utilizar essa nova funcionalidade.

Suponha que queiramos criar uma classe chamada “Pessoa” e que essa classe tenha atributos para guardar o nome e o sobrenome da pessoa. Sua implementação poderia ser algo como demonstrado abaixo:

    class Pessoa
    {
        private string _nome;
        private string _sobrenome;
    }

Agora imagine que nós desejemos adicionar um construtor nessa classe, que receberia os valores iniciais para os atributos nome e sobrenome. Poderíamos fazer isso da seguinte forma:

    class Pessoa
    {
        private string _nome;
        private string _sobrenome;

        public Pessoa(string nome, string sobrenome)
        {
            this._nome = nome;
            this._sobrenome = sobrenome;
        }
    }

Até aqui tudo muito simples, certo? Então veja agora como podemos simplificar esse código com a funcionalidade de “Primary Constructors” da nova versão do C#:

    class Pessoa(string nome, string sobrenome)
    {
        private string _nome = nome;
        private string _sobrenome = sobrenome;
    }

Entenderam a sacada? Ao invés de termos um construtor separado, podemos declarar a lista de parâmetros diretamente na frente do nome da classe, e dessa forma esses parâmetros ficam disponíveis no contexto de inicialização da classe. Com isso, podemos utilizá-los diretamente como valores na inicialização dos nossos atributos, como demonstrei no exemplo acima.

E se quisermos acessar esses parâmetros fora do contexto da inicialização, como, por exemplo, em um método? E se quisermos utilizar os parâmetros “nome” e “sobrenome” no override do método ToString?

    class Pessoa(string nome, string sobrenome)
    {
        private string _nome = nome;
        private string _sobrenome = sobrenome;

        public override string ToString()
        {
            return string.Format("{0} {1}", nome, sobrenome);
        }
    }

Isso não irá compilar, porque, como já mencionei anteriormente, esses parâmetros só ficam disponíveis no contexto da inicialização da classe. Após a inicialização, esses atributos vão para o espaço.

Parameters of a primary constructor can only be accessed in instance variable initializers and arguments to the base constructor.

Mas, sem stress! Caso você realmente queira acessar esses parâmetros fora do contexto de inicialização, basta alterar a declaração desse parâmetro de forma que explicitamente indiquemos ao compilador que queremos manter esse parâmetro em forma de atributo dentro de todo o escopo da classe (e não somente durante a sua inicialização). Para isso, podemos colocar o identificador de acesso “private” na declaração do parâmetro. Veja só:

    class Pessoa(private string nome, private string sobrenome)
    {
        private string _nome = nome;
        private string _sobrenome = sobrenome;

        public override string ToString()
        {
            return string.Format("{0} {1}", nome, sobrenome);
        }
    }

Simples, não? E com isso podemos até mesmo remover os atributos “_nome” e “_sobrenome”, pois nesse caso eles não serviriam para mais nada:

    class Pessoa(private string nome, private string sobrenome)
    {
        public override string ToString()
        {
            return string.Format("{0} {1}", nome, sobrenome);
        }
    }

Só para deixar bem evidente a quantidade de código inútil que podemos remover ao utilizar essa funcionalidade, veja o antes e depois.

Antes:

    class Pessoa
    {
        private string _nome;
        private string _sobrenome;

        public PessoaAntes(string nome, string sobrenome)
        {
            this._nome = nome;
            this._sobrenome = sobrenome;
        }

        public override string ToString()
        {
            return string.Format("{0} {1}", _nome, _sobrenome);
        }
    }

Depois:

    class Pessoa(private string nome, private string sobrenome)
    {
        public override string ToString()
        {
            return string.Format("{0} {1}", nome, sobrenome);
        }
    }

Sensacional, não? Espero que vocês também tenham gostado dessa nova funcionalidade. E no próximo artigo pretendo abordar rapidamente as outras novidades do C# vNext que ainda não comentei. Fiquem atentos e não deixem de conferir!

André Lima

One thought on “Novidades do C# vNext – Primary Constructors

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *