C#  -  Diferença entre Campos(Fields) e Propriedades(Properties)


 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($"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, atribuimos 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ê esta 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 atribuidos 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($"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($"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 atribuido 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($"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

"(Disse Jesus)Eu sou a porta; se alguém entrar por mim, salvar-se-á, e entrará, e sairá, e achará pastagens.
O ladrão não vem senão a roubar, a matar, e a destruir; eu vim para que tenham vida, e a tenham com abundância."
João 10:9,10

 

Referências:


José Carlos Macoratti