Back-End

15 jun, 2017

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

Publicidade

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