Aug 31, 2023

Structs em C# - diversão garantida - Parte 3/9: Inicialização de campos em structs

Read this post in English

Lisez cet post en french.

  1. Structs em C# - diversão garantida
  2. Rápida introdução à Value Types vs Reference Types.
  3. Inicialização de campos em estruturas (este post).
  4. Comportamento de construtores em estruturas.
  5. Outros cenários em que o comportamento de construtores em estruturas podem te surpreender.
  6. Argumentos default  em construtores de estruturas (você ainda não esta confuso ?).
  7. Modificador `required` do C# 11 não vai salvar seu c* trabalho.
  8. Estruturas usadas como valor default de argumentos.
  9. Bonus: Evolução das estruturas em C#. 

Continuando com nossa série sobre Value Types, dado o código abaixo, o que você espera que ele imprima (recomendo tentar responder antes de executá-lo):

Se você respondeu 0 (zero), acertou em cheio e provavelmente já possui um bom entendimento de como .NET/C# lida com instanciação/inicialização de campos de value types.; por outro lado, se você respondeu 32 provavelmente você foi levado ao engano. 

Neste post discutirei brevemente um dos aspectos responsáveis por esse comportamento: inicialização de campos em .NET, ou para ser mais preciso, em C#.

De uma forma simplificada, sempre que o compilador C# encontra a inicialização de um campo o mesmo simplesmente move o código de inicialização para os construtores, ou seja, inicializar um campo é equivalente a definir seu valor nos construtores (campos estáticos são inicializados em construtores estáticos), portanto, dado o código abaixo:

o compilador C# irá processá-lo como se o mesmo fosse escrito como:
o  que pode ser confirmado no código
IL gerado abaixo contudo,  caso não esteja familiarizado com código IL, tenha o seguinte em mente:

  • Não se deixe assustar com sua aparente complexidade.
  • Incluí comentários para enfatizar as partes principais.
  • Detalhes menos imporatntes foram omitidos.
  • Não é necessário compreender todos os detalhes para entender o conceito principal.

As linhas 6~22 e 25~36 definem, respectivamente, um construtor sem parâmetros e um que recebe um número inteiro; observe que o código relacionado à inicialização do campo (`f = 42`) foi introduzido em ambos (linhas 9~11 e 29~31).

No próximo post começaremos a explorar o comportamento de construtores em  estruturas (struct), também conhecido como a segunda parte do quebra-cabeça que explica por que o programa no topo do post imprime 0.

Como sempre, todo feedback é bem vindo.

Divirta-se!

No comments: