1. Propriedades automáticas
Em C#, propriedades (property) são tipo um meio termo entre campo e método. Basicamente, é um açúcar sintático que deixa o encapsulamento super prático. Você acessa a propriedade como se fosse um campo normal, mas por dentro pode ter qualquer lógica: validação, alterar outros campos, chamar métodos e até mandar um e-mail pra sua vó (mas isso não é recomendado). Na aula passada a gente escrevia propriedades na mão. Mas isso cansa rapidinho se você tem 100500 objetos simples, onde só precisa de "getter" e "setter" — sem lógica especial.
Chegou a vez das propriedades automáticas. Elas te livram do código repetitivo e deixam o C# cuidar do armazenamento do valor pra você.
Como era antes: propriedades manuais
Quando a gente quer esconder um campo, mas dar acesso por propriedade, normalmente faz assim:
public class Dog
{
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
}
Esse tipo de código é o clássico "boilerplate" chato. E na real, na maioria das vezes não precisa colocar nada nesses get/set! Só dar acesso — e pronto.
Como pode ser agora
No C# ficou bem mais simples: não precisa mais declarar o campo na mão — o compilador faz isso pra você. Só escrever:
public class Dog
{
public string Name { get; set; }
}
E já era. Dá pra ler e mudar o valor de Name de boa, e por baixo dos panos o compilador cria um campo privado que não dá pra acessar direto de fora.
O que rola nos bastidores? Quando você coloca public string Name { get; set; } no código, o compilador cria automaticamente um campo escondido tipo Name__BackingField. Toda vez que você acessa Name, ele chama o getter ou setter certo. O campo não aparece no código, mas existe — e com reflection dá até pra achar (mas aí já é outra história).
Qual a moral desse esquema? Primeiro, é bem mais curto e não precisa repetir tudo. Segundo, o código fica mais limpo: menos poluição visual, mais fácil de ler e manter. E por fim, é mais seguro — ninguém consegue mexer direto nos campos, o acesso é sempre pela propriedade.
2. Sintaxe das propriedades automáticas
Sintaxe super simples:
public class Dog
{
public string Name { get; set; }
public int Age { get; set; }
}
Agora nosso Dog ficou bem mais enxuto! Dá pra criar objetos e setar valores daquele jeito:
Dog myDog = new Dog();
myDog.Name = "Barbos";
myDog.Age = 4;
Resumindo
| Jeito | Sintaxe | Acesso ao valor |
|---|---|---|
| Campo | |
Acesso direto |
| Propriedade manual | |
Acesso via get/set |
| Propriedade automática | |
get/set + campo escondido |
3. Customizando acesso: só leitura, só escrita
Só leitura: get-only
Se a propriedade for só pra leitura (tipo o código de registro do pet), dá pra deixar ela só pra leitura — coloca get e não coloca set, ou faz o set privado. Esse valor só pode ser atribuído no construtor ou direto na declaração:
public class Dog
{
public string RegistrationCode { get; }
public Dog()
{
RegistrationCode = "DOG-001"; // Atribui valor no construtor
}
}
Agora só dá pra ler RegistrationCode de fora, não dá pra mudar. Ótimo pra proteger dados importantes de mudanças sem querer.
Outro jeito: set privado
public string Name { get; private set; }
Aí só dá pra mudar a propriedade dentro da classe (tipo em método ou construtor).
Só escrita: ideia ruim
Dá até pra fazer propriedade só pra escrita (set-only), mas é bem raro e não é recomendado — imagina um objeto que é tipo um "buraco negro": você joga coisa lá, mas nunca pega de volta.
4. Setters init-only
Um pouco de contexto
Antes, pra fazer um objeto imutável (immutable), só dava pra usar propriedades get e passar valores pelo construtor. Ok, funciona — mas nem sempre é prático. Agora o C# tem uma sintaxe nova: propriedades init-only.
Qual é a do setter init?
- Permite setar o valor da propriedade só na criação do objeto (ou seja no construtor ou no inicializador do objeto).
- Depois de criado, a propriedade vira só leitura.
- Perfeito pra classes "quase imutáveis", DTO, configs, modelos.
public class Dog
{
public string Name { get; init; }
public int Age { get; init; }
}
Agora dá pra fazer assim:
Dog dog = new Dog { Name = "Bobik", Age = 2 };
dog.Name = "Rex"; // Erro! Depois de criar - só leitura
No construtor também dá pra passar valores:
public Dog(string name, int age)
{
Name = name;
Age = age;
}
Resumo: quando pode atribuir
| Onde atribuir? | { get; set; } | { get; private set; } | { get; init; } |
|---|---|---|---|
| Fora da classe, depois de criar | ✅ | ❌ | ❌ |
| No construtor | ✅ | ✅ | ✅ |
| No inicializador | ✅ | ❌ | ✅ |
| Dentro da classe | ✅ | ✅ | ❌ (só no construtor) |
5. Usando na prática
Bora reescrever nossa classe Dog usando propriedades automáticas e init-only:
public class Dog
{
// Propriedade, só pode setar na inicialização
public string Name { get; init; }
public int Age { get; init; }
// Propriedade automática pro estado atual
public bool IsHungry { get; set; }
// Método, ações do cachorro
public void Bark()
{
Console.WriteLine($"{Name} diz: Au!");
}
}
Agora dá pra criar Dog assim:
Dog dog = new Dog { Name = "Sharik", Age = 3, IsHungry = true };
dog.Bark(); // vai mostrar: Sharik diz: Au!
dog.IsHungry = false; // essa propriedade pode mudar depois de criar
dog.Name = "Barbos"; // Erro! Propriedade só pra inicialização
6. Propriedades automáticas com valores iniciais
No C# tudo é feito pra facilitar sua vida. Dá até pra colocar valor inicial direto na propriedade:
public class Dog
{
public string Name { get; set; } = "SemNome";
public int Age { get; set; } = 0;
}
Ou com init:
public class Dog
{
public string Name { get; init; } = "Filhote";
public int Age { get; init; } = 0;
}
Agora se não passar Name na criação, vai ser "Filhote".
7. Propriedades automáticas com níveis de acesso diferentes
Dá pra fazer a propriedade ter leitura e escrita com modificadores de acesso diferentes:
public class Dog
{
public string Name { get; private set; }
public int Age { get; private set; }
public Dog(string name, int age)
{
Name = name;
Age = age;
}
}
Nesse caso, só dá pra mudar nome e idade dentro da classe Dog, tipo em métodos ou no construtor.
Comparando propriedades manuais e automáticas
| Abordagem | Dificuldade de escrever | Controle no set/get | Mudança depois de criar | Uso em modelos |
|---|---|---|---|---|
| Propriedade manual | Longo | Total | Qualquer | Quando precisa de lógica |
| Propriedade automática | Curto | Não | Qualquer ou privado | Quase sempre |
| init-only automática | Curto | Não | Só na criação | DTO, configs |
8. Erros comuns ao usar propriedades
Erro nº1: tentar atribuir valor a propriedade get-only fora do construtor.
Se a propriedade tem só get, o compilador não deixa mudar o valor em outro lugar. Só pode atribuir no construtor ou direto na declaração. Esqueceu — vai dar erro de compilação.
Erro nº2: confundir campo com propriedade.
Quando troca um campo normal por propriedade automática, tem que garantir que o resto do código não acessa o campo direto. Campo e propriedade são coisas diferentes, e se deixar acesso antigo, o compilador pode dar erro ou o programa agir estranho.
Erro nº3: set privado sem entender as consequências.
Se a propriedade tem set privado, mas o resto do código ainda tenta atribuir valor — vai dar erro. Isso acontece muito sem querer, principalmente copiando código dos outros. Sempre confere se o set tá acessível onde você quer usar.
GO TO FULL VERSION