Neste artigo, vou apresentar as diferenças conceituais entre Campos e Propriedades na linguagem C#.
Quando criamos uma classe na linguagem C#, podemos definir na classe propriedades e campos, bem como métodos, eventos e índices. Esses componentes da classe são conhecidos como membros da classe.
Usando Campos
Assim, ao criar uma classe, podemos criar campos para armazenar informações.
Exemplo:
using System; namespace CSharp_CamposPropriedades { public class Teste { public int campo1; public string campo2; } class Program { static void Main(string[] args) { Teste t = new Teste(); t.campo1 = 2017; t.campo2 = "Macoratti .net"; Console.WriteLine(quot;campo1 = {t.campo1} campo2 = {t.campo2}"); Console.ReadKey(); } } }
Neste exemplo, criamos a classe Teste com dois campos públicos: campo1 do tipo int e campo2 do tipo string.
No método Main(), criamos uma instância da classe Teste, o objeto t, atribuímos valores aos campos e, a seguir, exibimos o resultado usando o novo operador $.
Pois bem, neste exemplo, os campos campo1 e campo2 estão expondo o estado de um objeto (t) da classe ao mundo exterior.
Um dos pilares da programação orientada a objetos é justamente o encapsulamento dos dados da classe, e isso significa que o trabalho interno de uma classe deve ser escondido do mundo exterior.
Neste exemplo, ao definir os campos campo1 e campo2 como público, você está expondo a implementação interna da classe, e isso não é uma boa prática. Nessa abordagem, não temos controle como os dados serão atribuídos ou acessados.
Por isso, ao invés de usar Campos, podemos usar Propriedades.
Usando propriedades
Uma propriedade é um membro que fornece um mecanismo flexível para ler, escrever ou calcular o valor de um campo particular.
Portanto, envolvemos Campos com Propriedades para nos dar a capacidade de alterar a implementação sem quebrar o código e para permitir um maior controle sobre os membros da classe que desejamos expor ou ocultar.
Dessa forma, as propriedades expõem campos, o que significa que permitem que uma classe exponha uma forma pública de obter e definir valores, enquanto oculta a implementação.
Exemplo:
using System; namespace Exemplo2 { public class Teste { public int Campo1 { get; set; } public string Campo2 { get; set; } } class Program { static void Main(string[] args) { Teste t = new Teste(); t.Campo1 = 2017; t.Campo2 = "Macoratti .net"; Console.WriteLine(quot;campo1 = {t.Campo1} campo2 = {t.Campo2}"); Console.ReadKey(); } } }
Neste exemplo, estamos definindo duas propriedades Campo1 e Campo2 usando a forma resumida conhecida como Propriedades Automáticas.
Observe que declaramos a propriedade com get e set onde:
- get – significa que estamos dando acesso de leitura a essa propriedade;
- set – significa que estamos dando acesso de escrita a essa propriedade.
Assim se eu quiser que somente métodos internos dessa classe possam escrever na propriedade Campo1, eu posso definir o código assim:
Para isso, vou definir o set como privado:
using System; namespace Exemplo2 { public class Teste { public int Campo1 { get; private set; } public string Campo2 { get; set; } } }
Posso também impedir que a propriedade Campo1 seja alterada, sendo a atribuição do seu valor feita somente no construtor da classe:
Para isso, vou definir apenas o get e criar um construtor onde o valor será passado para a propriedade Campo1:
using System; namespace Exemplo2 { public class Teste { public int Campo1 { get; } public string Campo2 { get; set; } public Teste(int valor) { Campo1 = valor; } } class Program { static void Main(string[] args) { Teste t = new Teste(2017); t.Campo2 = "Macoratti .net"; Console.WriteLine(quot;campo1 = {t.Campo1} campo2 = {t.Campo2}"); Console.ReadKey(); } } }
Posso aumentar o controle sobre as propriedades definindo get e set e, assim, declarando campos privados para tratar o valor que foi atribuído ou lido das propriedades.
using System; namespace Exemplo3 { public class Teste { private int campo1; public int Campo1 { get { return campo1; } set { if(value < 2017) { campo1 = value; } else { throw new Exception("Valor para Campo1 inválido"); } } } public string Campo2 { get; set; } } class Program { static void Main(string[] args) { Teste t = new Teste(); try { t.Campo1 = 2018; t.Campo2 = "Macoratti .net"; Console.WriteLine(quot;campo1 = {t.Campo1} campo2 = {t.Campo2}"); } catch(Exception ex) { Console.WriteLine(ex.Message); } Console.ReadKey(); } } }
Neste exemplo, definimos a propriedade pública Campo1 e o campo privado campo1 para armazenar a informação da propriedade. Assim, o set da propriedade guarda o valor (representado pela palavra-chave value) no campo privado e o get retorna o valor que está neste campo privado.
Observe que, agora, definimos uma restrição no set de forma que somente valores menores que 2017 possam ser atribuídos à propriedade Campo1. Caso contrário, lançamos uma exceção.
Dessa forma, as propriedades fornecem um nível de abstração que permite alterar os campos sem afetar a maneira externa como eles são acessados por quem for usar a sua classe.
As propriedades têm a vantagem principal de permitir que você altere a forma como os dados de um objeto são acessados sem quebrar sua interface pública.
Pegue o projeto completo aqui: CSharp_CamposPropriedades.zip