C# 9.0 - Propriedades init e record \| TreinaWeb               Promoção no ar   Matricule-se agora e garanta **54% de desconto**  

  Termina em   Tempo restante da oferta: 13 Horas 

 54 Min 

 51 Seg 

   Tempo restante da oferta: 13 54 51 

  [Assinar →](https://www.treinaweb.com.br/checkout/pagamento/plano/anual?cupom=TW-SCLIENTE26) 

   [                ](https://www.treinaweb.com.br)  Explorar  

 [ Quanto custa? ](#assinatura) [ FAQ ](https://www.treinaweb.com.br#faq) [Matricule-se](#assinatura) [ Entrar ](https://www.treinaweb.com.br/login) 

     [ Início ](https://www.treinaweb.com.br) [ Artigos ](https://www.treinaweb.com.br/blog) C# 9.0 - Propriedades init e record  [ C# ](https://www.treinaweb.com.br/blog/categoria/csharp) 

# C# 9.0 - Propriedades init e record

 Já estamos no C# 9.0, a nova versão lançada no .NET Conf 2020 trouxe uma série de novos recursos, veja neste artigo dois deles: propriedades init e record.

 [ Wladimilson M. Nascimento ](https://www.treinaweb.com.br/blog/autor/wladimilson-m-nascimento) 6 anos atrás

  ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/11/C-SHARP-PROPRIEDADES-INIT-RECORD.png)  

Durante a [.NET Conf deste ano](https://www.dotnetconf.net/) (2020), a versão 5.0 do .NET foi lançada, junto também saiu a versão final C# 9.0. Como em a cada nova versão da linguagem, esta nona trouxe uma série de recursos que visam facilitar a vida do desenvolvedor e melhorar a legibilidade do código.

Neste e nos próximos artigos mostrarei um pouco desses recursos, começando pelas propriedades init e record.

## Propriedades de inicialização

Introduzido na versão 3 do C#, inicializadores de objeto é um ótimo recurso que permite que o objeto seja criado de forma simples e clara. Permitindo inicializar todas as propriedades dele em uma única instrução. Um exemplo simples disso seria:

```csharp
var pessoa = new Pessoa { Nome = "Carlos Silva", Idade = 33 };

```

Este recurso possibilita que o objeto seja criado sem a definição de um construtor. No caso do exemplo acima, a classe poderia ser declarada da seguinte forma:

```csharp
public class Pessoa
{
    public string? Nome { get; set; }
    public int Idade { get; set; }
}

```

Mas uma grande limitação dele é que as propriedades dos objetos precisam ser mutáveis para que funcione. Isso ocorre porque inicialmente é chamado o construtor da classe (sem parâmetros no caso do exemplo) e só depois que os setters das propriedades são chamados.

Para resolver isso na versão 9.0 foi introduzido o conceito de “propriedades init”. Este tipo de propriedade utiliza o acessor `init`, que pode ser utilizado no lugar do `set`:

```csharp
public class Pessoa
{
    public string? Nome { get; init; }
    public int Idade { get; init; }
}

```

Desta forma, a propriedade só pode ser inicializada utilizando o inicializador de objeto:

```csharp
var pessoa = new Pessoa { Nome = "Alex Silva", Idade = 33 }; //Ok
pessoa.Idade = 32; //Será gerado um erro

```

Na prática significa que o estado do objeto não poderá ser alterado após a sua inicialização.

### Acessor init com campos readonly

Como com o acessor `init` as propriedades só podem receber dados durante a incialização do objeto, ele permite a definição de campos *readonly*:

```csharp
public class Pessoa
{
    private readonly string nome = "";
    private readonly int idade = 0;

    public string Nome 
    { 
        get => nome; 
        init => nome = (value ?? throw new ArgumentNullException(nameof(Nome)));
    }
    public int Idade 
    { 
        get => idade; 
        init => idade = (value ?? throw new ArgumentNullException(nameof(Idade)));
    }
}

```

Desta forma teremos um comportamento parecido com o obtido quando os campos `readonly` são inicializados no construtor da classe.

## Records (registros)

Um conceito base da programação orientada à objetos é que um objeto possui uma forte identidade e encapsula estados mutáveis ao longo da sua vida. Este tipo de conceito é facilmente aplicável no C#, entretanto as vezes você pode desejar o inverso, que um objeto seja imutável e quando isso ocorre o C# tende a atrapalhar esta implementação.

Para resolver este problema, na versão 9 foi introduzido o conceito de “record” (registro). Este novo tipo de objeto pode ser declarado como uma classe normal, bastando substituir a cláusula `class` por `record`:

```csharp
public record Pessoa
{
    public string? Nome { get; init; }
    public int Idade { get; init; }
}

```

Um “record” ainda é uma classe, mas ao utilizar a cláusula `record`, o C# irá adicionar aos objetos dela alguns comportamentos de [objetos value-type](https://www.treinaweb.com.br/blog/gerenciamento-de-memoria-no-c-stack-heap-value-types-e-reference-types/). A classe não deixa de ser um [referece-type](https://www.treinaweb.com.br/blog/gerenciamento-de-memoria-no-c-stack-heap-value-types-e-reference-types/), mas na prática passa a ser bem parecida com estruturas. Ou seja, os objetos dela passam a serem definidos pelo seu conteúdo e não a sua identidade.

Mesmo que ainda seja possível criar “records” mutáveis, eles foram criados para melhorar o suporte a objetos imutáveis.

## Cláusula with

Quando se trabalha com objetos imutáveis e é necessário representar um novo estado, pode ser um pouco trabalhoso criar novos objetos a partir de um objeto existente. Por exemplo, se for necessário alterar uma propriedade de um objeto imutável, deve-se criar um objeto que seja cópia de um existente, mas a única diferença entre eles será a propriedade que foi alterada. Esta técnica é chamada de *mutação não destrutiva*.

E para facilitar a implementação dela com “records”, também foi introduzido a cláusula `with`:

```csharp
var pessoa = new Pessoa { Nome = "Alex Silva", Idade = 33 };
var novaPessoa = pessoa with { Idade = 32 };

```

Note que a expressão `with` acima está utilizando a sintaxe dos inicializados de objeto. Desta forma, ela só pode ser utilizada em propriedades que tenham definido o acessor `set` ou `init`.

Nos bastidores esta cláusula irá copiar todo o conteúdo do objeto original (`pessoa`) e alterar o valor das propriedades definidas na expressão `with` (`Idade`).

### Igualdade

Um dos comportamentos de value-type adicionados aos “records” é o de igualdade. Todos os objetos do C# herdam o método `Equals(object)` da classe `object` e isso não é diferente para os “records”. Este método é utilizado quando os objetos estão sendo comparados.

Objetos reference-type, são comparados pela referência; e value-type, são comparados pelos valores. E mesmo que um “record” seja considerado um objeto reference-type, eles são comparados pelos valores:

```csharp
var pessoa = new Pessoa { Nome = "Alex Silva", Idade = 33 };
var novaPessoa = pessoa with { Idade = 32 };
var outraPessoa = novaPessoa with { Idade = 33 };

Console.WriteLine(Object.ReferenceEquals(pessoa, outraPessoa));//False
Console.WriteLine(Object.Equals(pessoa, outraPessoa));//True

```

Com isso, se dois “records” possuírem os mesmos valores, eles serão considerados iguais. Este comportamento também irá ocorrer caso aplique os operadores `==` e `!=`, já que para manter a consistência, “records” implementam a interface `IEquatable` e sobrescrevem esses operadores.

Mas é importante lembrar que igualdade e mudança de estado não combinam muito bem. Um problema dos “records” é que a alteração dos dados pode gerar à alteração do código retornado pelo método `GetHashCode` e se o objeto for salvo em uma tash table, também muda o resultado dela.

Então é necessário ter cuidado quando se altera um “record”.

### Herança

Assim como qualquer classe, “record” também podem ser herdados por outros “records”:

```csharp
public record Funcionario : Pessoa
{
    public int ID;
}

```

Os “records” filhos tem acesso à todas as propriedades do “record” pai:

```csharp
var funcionario = new Funcionario { Nome = "José Silva", Idade = 44, ID = 1234 };

```

Que também podem ser acessadas com a expressão `with`:

```csharp
var outroFuncionario = funcionario with { Nome = "Maria Santos", ID = 2345 };

```

E podem ser comparadas com o operador de igualdade:

```csharp
Console.WriteLine(funcionario == outroFuncionario);//False

```

### Record posicional

Nos exemplos anteriores todos os nossos objetos “record” foram criados utilizando o inicializador de objetos ou a expressão `with`, mas também é possível definir um construtor, e até um desconstrutor, no “record”:

```csharp
public record Pessoa
{
    public string? Nome { get; init; }
    public int Idade { get; init; }
    public Pessoa (string nome, int idade) 
      => (Nome, Idade) = (nome, idade);
    public Descontruct (out string nome, out int idade) 
      => (Nome, Idade) = (nome, idade);
}

```

Caso o construtor e o desconstrutor definidos receber por parâmetro valores para todas as propriedades do “record”, a sua declaração pode ser encurtada para:

```csharp
public record Pessoa (string Nome, int Idade);

```

Nos bastidores o C# se encarregará de criar as propriedades, o construtor e desconstrutor do “record” definido:

```csharp
var pessoa = new Pessoa("Carlos Silva", 33); //Construtor
var (nome, idade) = pessoa;//Desconstrutor

```

É importante frisar que as propriedades serão definidas com o acessor `init`. E caso queira ter mais controle sobre elas, você pode desabilitar a auto geração definindo propriedades com o mesmo nome no bloco do “record”:

```csharp
public record Pessoa (string Nome, int Idade)
{
    public string? Nome { get; init; } = Nome;
    public int Idade { get; init; } = Idade;
}

```

Neste caso serão gerados apenas o construtor e desconstrutor.

Este tipo de declaração reduzida também pode ser utilizada durante a herança:

```csharp
public record Funcionario (string Nome, int Idade, int ID) : Pessoa(Nome, Idade);

```

Com isso finalizamos este artigo. No próximo abordarei outros recursos do C# 9.0. Até lá!

- [ #C# ](https://www.treinaweb.com.br/blog/tag/csharp)
- [ #C# 9.0 ](https://www.treinaweb.com.br/blog/tag/c-9-0)
- [ #Record ](https://www.treinaweb.com.br/blog/tag/record)

Autor

 ![Wladimilson M. Nascimento](//secure.gravatar.com/avatar/f0dd442f156a3eacd2880e9cd0eafbd1?d=mm)

## Wladimilson M. Nascimento

 Instrutor, nerd, cinéfilo e desenvolvedor nas horas vagas. Graduado em Ciências da Computação pela Universidade Metodista de São Paulo. 

 [Todos os artigos](https://www.treinaweb.com.br/blog/autor/wladimilson-m-nascimento)  

## Continue estudando

 Transforme leitura em prática com os cursos e formações da TreinaWeb.

 [Ver cursos](https://www.treinaweb.com.br/cursos)   

  Continue lendo

## Artigos relacionados

- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/11/C-SHARP-PROPRIEDADES-INIT-RECORD-400x280.png)  [ C# ](https://www.treinaweb.com.br/blog/categoria/csharp) 

     6 anos atrás

    ##  [ C# 9.0 - Programas top-level e Pattern Matching ](https://www.treinaweb.com.br/blog/c-9-0-programas-top-level-e-pattern-matching) 

     Dando continuidade ao nosso estudo do C# 9.0, neste artigo veremos dois novos recursos dele: Programas top-leve e Pattern Matching.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/11/C-SHARP-PROPRIEDADES-INIT-RECORD-400x280.png)  [ C# ](https://www.treinaweb.com.br/blog/categoria/csharp) 

     6 anos atrás

    ##  [ C# 9.0 - Inteiros nativos e inferência de tipos ](https://www.treinaweb.com.br/blog/c-9-0-inteiros-nativos-e-inferencia-de-tipos) 

     Conheça os novos tipos de dados introduzidos no C# 9.0, os inteiros nativos e os novos recursos da inferência de tipos.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/05/IDE-PYTHON-400x280.png)  [ Python ](https://www.treinaweb.com.br/blog/categoria/python) 

     6 anos atrás

    ##  [ Orientação a objetos em Python ](https://www.treinaweb.com.br/blog/orientacao-a-objetos-em-python) 

     Veja neste artigo os principais conceitos do paradigma orientação a objetos e como eles se aplicam no Python.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2021/01/introducao-ao-maven-aprenda-como-criar-e-gerenciar-projetos-java-400x280.png)  [ Java ](https://www.treinaweb.com.br/blog/categoria/java) 

     6 anos atrás

    ##  [ Introdução ao Maven, aprenda como criar e gerenciar projetos Java ](https://www.treinaweb.com.br/blog/introducao-ao-maven-aprenda-como-criar-e-gerenciar-projetos-java) 

     Neste artigo veremos como instalar o Maven e como podemos utilizá-lo para nos auxiliar na criação e no gerenciamento de dependência de um projeto Java.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2018/08/07161700/gerenciamento-python-400x280.png)  [ Python ](https://www.treinaweb.com.br/blog/categoria/python) 

     4 anos atrás

    ##  [ Empacotando e publicando pacotes Python no PyPi ](https://www.treinaweb.com.br/blog/empacotando-e-publicando-pacotes-python-no-pypi) 

     Neste artigo iremos aprender como funciona o processo de empacotar e distribuir nossos próprios pacotes Python no PyPi.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/03/18140521/AUTOMAPPER-400x280.png)  [ Desenvolvimento Back-end ](https://www.treinaweb.com.br/blog/categoria/desenvolvimento-back-end) 

     7 anos atrás

    ##  [ Utilizando AutoMapper no C# ](https://www.treinaweb.com.br/blog/utilizando-automapper-no-c) 

     Conheça a biblioteca AutoMapper e aprenda como implementá-la em uma aplicação C#.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2021/05/code-3-400x280.png)  [ C# ](https://www.treinaweb.com.br/blog/categoria/csharp) 

     10 anos atrás

    ##  [ As mudanças de Expression-bodied members no C# 7 ](https://www.treinaweb.com.br/blog/as-mudancas-de-expression-bodied-members-no-csharp-7) 

     Conheça as mudanças de Expression-bodied members no C# 7.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2021/05/tuplas-400x280.png)  [ C# ](https://www.treinaweb.com.br/blog/categoria/csharp) 

     10 anos atrás

    ##  [ Tuplas no C# 7 ](https://www.treinaweb.com.br/blog/tuplas-no-csharp-7) 

     Aprenda o que são e como funcionarão as tuplas no C# 7.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2018/01/19114832/C-SHARP-7-400x280.png)  [ C# ](https://www.treinaweb.com.br/blog/categoria/csharp) 

     9 anos atrás

    ##  [ Generalizando tipos de retornos assíncronos no C# 7.0 ](https://www.treinaweb.com.br/blog/generalizando-tipos-de-retornos-assincronos-no-csharp-7) 

     Aprenda a criar um tipo que pode ser retornado pelos métodos assíncronos do C#.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2022/09/POSITIONS-CSS-400x280.jpg)  [ CSS ](https://www.treinaweb.com.br/blog/categoria/css) 

     4 anos atrás

    ##  [ Position, estilizando elementos com CSS. ](https://www.treinaweb.com.br/blog/position-estilizando-elementos-com-css) 

     Neste artigo nos iremos aprender sobre position em elementos no CSS, e sua importância para estilizações das nossas páginas web.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/11/03082200/ORM-CAPA-400x280.png)  [ PHP ](https://www.treinaweb.com.br/blog/categoria/php) 

     7 anos atrás

    ##  [ O que é ORM? ](https://www.treinaweb.com.br/blog/o-que-e-orm) 

     Nesse artigo aprenderemos o que é ORM, quais problemas ele resolve, os padrões mais usados e quais os principais ORMs do mercado.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2021/05/grid-layout-400x280.png)  [ CSS ](https://www.treinaweb.com.br/blog/categoria/css) 

     10 anos atrás

    ##  [ Começando com o novo CSS Grid Layout ](https://www.treinaweb.com.br/blog/comecando-com-o-novo-css-grid-layout) 

     Aprenda um pouco mais sobre o CSS Grid Layout, agora com suporte completo pelo Firefox e Chrome.

     Ler artigo

## Um ano de acesso total para você viver de programação.

 Todos os cursos e formações da TreinaWeb numa única assinatura, com professores que atuam no mercado, suporte direto e certificados. Do primeiro `console.log` ao mercado de trabalho.

- **1 ano** de acesso a **todos os cursos**
- Cursos novos **toda semana**
- Suporte **direto com professores**
- Plano de carreira **personalizado**
- **Certificados digitais** inclusos
- **Aplicativos** para Android e iOS, com **acesso offline**

    **Garantia incondicional de satisfação** 

 Teste por 7 dias e, se não fizer sentido para você, devolvemos seu dinheiro.

### Acesso completo a todos os cursos e dezenas de Formações.

 12 meses 

  Economize R$ 840,00  54% OFF 

 de 12x R$ 129,00 por apenas

 12x  R$ 59,00

 sem juros no cartão de crédito ou R$ 599,00 à vista

  Oferta termina em  **13h 54min 51s**

- Acesso imediato e ilimitado durante 1 ano.
- Plano de carreira personalizado.
- Suporte direto com professores.
- E muito mais!

 [Matricule-se agora](https://www.treinaweb.com.br/checkout/pagamento/plano/anual?cupom=TW-SCLIENTE26)

     [                ](https://www.treinaweb.com.br)

 Escola online de programação, tecnologia e IA.

- [  ](https://www.facebook.com/TreinaWeb/)
- [  ](https://www.instagram.com/treinaweb/)
- [  ](https://www.youtube.com/user/TreinaWeb)
- [  ](https://twitter.com/treinaweb)
- [  ](https://www.linkedin.com/company/treinaweb)
- [  ](https://github.com/treinaweb)

## Inscreva-se em nossa newsletter

Receba lançamentos, promoções e novidades.

   Seu nome     Seu WhatsApp     Seu melhor e-mail   Inscrever-se 

## Cursos

- [ Base para Devs ](https://www.treinaweb.com.br/categoria/base-para-devs)
- [ Front-end ](https://www.treinaweb.com.br/categoria/desenvolvimento-front-end)
- [ Back-end ](https://www.treinaweb.com.br/categoria/desenvolvimento-back-end)
- [ Mobile ](https://www.treinaweb.com.br/categoria/desenvolvimento-mobile)
- [ Bancos de Dados ](https://www.treinaweb.com.br/categoria/bancos-de-dados)
- [ Cloud ](https://www.treinaweb.com.br/categoria/cloud-computing)
- [ IA ](https://www.treinaweb.com.br/categoria/ia)
- [ E mais ](https://www.treinaweb.com.br/categoria/e-mais)
- [ Ver todos os cursos ](https://www.treinaweb.com.br/cursos)

## Conteúdo

- [ Formações ](https://www.treinaweb.com.br/formacoes)
- [ Projetos práticos ](https://www.treinaweb.com.br/projetos-praticos)
- [ Direto ao ponto ](https://www.treinaweb.com.br/direto-ao-ponto)
- [ Planos ](https://www.treinaweb.com.br#assinatura)
- [ Depoimentos ](https://www.treinaweb.com.br#depoimentos)
- [ Comunidade ](https://www.treinaweb.com.br#comunidade)
- [ Corpo docente ](https://www.treinaweb.com.br#docente)

## A empresa

- [ Sobre a TreinaWeb ](https://www.treinaweb.com.br#sobre)
- [ Perguntas frequentes ](https://www.treinaweb.com.br#faq)
- [ Vantagens de estudar na TreinaWeb ](https://www.treinaweb.com.br/vantagens-de-estudar-na-treinaweb)
- [ Cursos para empresas ](https://www.treinaweb.com.br/empresas)
- [ Sugira um novo curso ](https://www.treinaweb.com.br/sugerir-curso)
- [ Trabalhe conosco ](https://www.treinaweb.com.br/trabalhe-conosco)
- [ Artigos ](https://www.treinaweb.com.br/blog)
- [ Desenvolvedores e agentes ](https://www.treinaweb.com.br/developers)
- [ Contato ](https://www.treinaweb.com.br/contato)
- [ Política de privacidade ](https://www.treinaweb.com.br/politica-de-privacidade)
- [ Termos de uso ](https://www.treinaweb.com.br/termos-de-uso)

## Baixe nosso aplicativo

 [   Disponível na **App Store**  ](https://apps.apple.com/us/app/treinaweb/id1322729447) [   Disponível no **Google Play**  ](https://play.google.com/store/apps/details?id=br.com.treinaweb.mobile) 

  Av. Paulista, 1765, Conj 71 e 72 · Bela Vista · São Paulo · SP · 01311-200   © 2004 – 2026 TreinaWeb Tecnologia LTDA · CNPJ 06.156.637/0001-58
