1. Introdução
Bora começar pelos problemas que aparecem quando a gente usa campos diretamente. Se você declarar um campo como public, qualquer um pode mudar ele na hora, de qualquer lugar do programa:
public class Dog
{
public string Name;
}
Dog dog = new Dog();
dog.Name = ""; // O_o ... tipo "nome do cachorro = string vazia"!
O usuário pode colocar no campo Name uns valores nada a ver, até uns que não fazem sentido pro seu domínio: string vazia, nome gigante, ou até null. É tipo se alguém montasse seu armário novo da IKEA e você desse acesso total pra fábrica de madeira.
Lembrando que encapsulamento é quando o objeto controla os próprios dados. A gente não deixa qualquer um mexer nas entranhas, mas oferece umas "portinhas" especiais — as propriedades (Properties), por onde rola o acesso ao campo, mas com chance de validar, logar, modificar ou reagir de algum jeito quando o valor muda.
2. Definição e sintaxe
Propriedade é um membro especial da classe, que parece um campo, mas na real é um par de métodos especiais: getter (pega o valor) e setter (define o valor). Com propriedade, dá pra:
- Liberar (ou bloquear) leitura/escrita dos dados;
- Adicionar validação ou lógica quando alguém acessa os dados;
- Esconder o campo interno e até guardar o valor em outro lugar.
A propriedade é declarada quase igual a um campo, só que com chaves e as palavras get e set dentro.
[modificador_de_acesso] tipo NomePropriedade
{
get { ... }
set { ... }
}
Olha só um exemplo pro nosso Dog:
public class Dog
{
private string _name; // campo interno (private!)
public string Name
{
get { return _name; } // "getter": pega o nome
set { _name = value; } // "setter": define o nome
}
}
Obs: underline geralmente é usado pra campos privados (_name). É padrão de estilo em C#.
3. Como funciona a propriedade
A propriedade é tipo um "guarda" entre os dados internos do objeto e o mundo de fora. Exemplo:
Dog dog = new Dog();
dog.Name = "Sharik";
Console.WriteLine(dog.Name);
Explicando:
- Quando o programa chega em dog.Name = "Sharik"; — aí rola a chamada do método set da propriedade, e você pode colocar qualquer validação ali (tipo checar se o nome não tá vazio).
- No Console.WriteLine(dog.Name); é chamado o método get, que só devolve o valor atual ou, se quiser, calcula algo na hora.
Parece campo normal, mas na real tá tudo sob controle!
4. Por que propriedades são "Best Practice"
Na maioria das vezes, a gente não deixa acesso direto aos campos internos do objeto. Mesmo que agora não precise de validação, acostumar a usar propriedades salva sua pele quando as regras mudam.
Exemplo de "validação" na hora de definir:
public class Dog
{
private string _name;
public string Name
{
get { return _name; }
set
{
if (string.IsNullOrWhiteSpace(value))
{
throw new ArgumentException("Nome do cachorro não pode ser vazio!");
}
_name = value;
}
}
}
Agora isso aqui:
dog.Name = ""; // Vai lançar exceção!
… protege nosso objeto de valores sem sentido.
5. Propriedades: só leitura, só escrita e normais
Às vezes, você só quer deixar ver o valor (tipo o ano de nascimento do cachorro, não dá pra mudar), ou só deixar definir (raro, mas vai que você quer fazer algo misterioso).
- Só leitura: só escreve get, tira o set.
- Só escrita: só escreve set, tira o get.
Exemplos:
public class Dog
{
private int _birthYear = 2018;
// Só leitura
public int BirthYear
{
get { return _birthYear; }
}
// Só escrita (bem raro)
public string Secret
{
set { /* faz algo com value */ }
}
}
6. Propriedades vs Campos
| Campo | Propriedade | |
|---|---|---|
| Sintaxe | |
|
| Acesso | Direto | Pelo get/set |
| Validação | Não tem | Dá pra colocar no set/get |
| Extensibilidade | Não tem | Dá pra mudar a qualquer hora |
| Integração com IDE | Aparece como campo | Aparece como propriedade (importante pra frameworks) |
Ilustração: Como funciona a propriedade
sequenceDiagram
participant User as Usuário do objeto
participant Dog as Objeto Dog
participant Field as Campo privado _name
User->>Dog: dog.Name = "Ryzhik"
Dog->>Dog: set Name("Ryzhik")
Dog->>Field: _name = "Ryzhik"
User->>Dog: print(dog.Name)
Dog->>Dog: get Name()
Dog->>Field: lê _name
Dog->>User: retorna "Ryzhik"
7. Erros comuns e pegadinhas
Bora ver onde pode dar ruim.
Erro clássico — confundir campo e propriedade, e acabar expondo dado privado sem querer:
public string name; // Isso é campo! Fica visível em todo lugar, perigoso!
Melhor assim:
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
Propriedades estáticas existem pra guardar valores comuns pra todos os objetos. Mas usa com cuidado.
Curiosidade: se a propriedade só tem get e nenhum construtor, não dá pra mudar nunca — isso se chama immutable property e é muito usado nos jeitos modernos de projetar (a gente vai falar disso nas aulas sobre record e imutabilidade de dados).
GO TO FULL VERSION