E aê, pessoal!

Chegamos ao terceiro artigo que compõe a sétima parte da série introdução ao .Net Framework. Nessa sétima parte estamos falando sobre membros de tipos. Nessa publicação falarei sobre propriedades. Como de costume, em todas as publicações dessa série estou postando os link`s dos post`s anteriores para aqueles que caíram aqui de paraquedas e tem interesse em conferir os outros tópicos, segue abaixo:

1 - Introdução ao .Net Framework - Parte 1 - Do que é composto, compialçao.

2 - Introdução ao .Net Framework - Parte 2 - CLR, CTS, FCL, CLS.

3 - Introdução ao .Net Framework - Parte 3 - Tipos.

4 - Introdução ao .Net Framework - Parte 4 - Conversão/Casting de tipos.

5 - Introdução ao .Net Framework - Parte 5 - Namespace e Assemblies.

6 - Introdução ao .Net Framework - Parte 6 - Boxing e Unboxing.

7 - Introdução ao .Net Framework - Parte 7/1 - Membros de tipos - Constantes, Campos.

8 - Introdução ao .Net Framework - Parte 7/2 - Mebros de tipos - Métodos.

INTRODUÇÃO

            Uma propriedade é um membro de um tipo que permite definir informações referentes ao mesmo. Mais conhecida como property, as propriedades oferecem flexibilidade para ler, gravar ou calcular seus valores.

Propriedades permitem que métodos sejam utilizados de uma forma simples, como se fossem campos. Propriedades podem ser declaradas sem parâmetros ou com parâmetros, nesse segundo caso, são denominadas indexadores. Não falaremos de indexadores nesse artigo.

Propriedades

Durante o tempo de execução de uma aplicação, informações de campos de tipos são usadas e ou alteradas diversas vezes. Veja no Exemplo 1 a definição de um tipo com alguns campos.

Exemplo 1:

C#

[sourcecode language="csharp"]

public class Carro
{
public string Cor;
public decimal Km;
}
[/sourcecode]

Veja agora o uso desses campos através de uma instância do tipo no Exemplo2.

Exemplo 2:

C#

[sourcecode language="csharp"]

class Program
{
static void Main(string[] args)
{
Carro Carro = new Carro(); //criando uma instância de carro
Carro.Cor = "Branco"; //gravando valor no campo Cor
Carro.Km = 10.000; //gravando valor no campo Km

System.Console.WriteLine("Meu carro é da cor " + Carro.Cor + " e está com " + Carro.Km + " quilometros rodados."); //Lendo os campos Cor e Km
}
}
[/sourcecode]

Com o advento da programação orientada a objeto temos a disposição o benefício de encapsulamento de dados. Isso significa que podemos proteger as informações de estado de um tipo. Proteger? Isso mesmo, observe novamente o Exemplo 2, o que impediria de informarmos o valor -200 para o campo quilometragem? Se você disse: Nada! Acertou. Se isso acontecesse, as informações referentes a essa instância do tipo ficariam inconsistentes, pois, não existe um carro com a quilometragem -200. Veja no Exemplo 3 o mesmo tipo Carro mostrado no Exemplo 1 implementado com propriedades.

Exemplo 3

C#

[sourcecode language="csharp"]
public class Carro
{
private string Cor
{
get {return Cor;}
set {Cor = value;}
}

private decimal Km
{
get {return Km;}
set {Km = value;}
}
}
[/sourcecode]

Pessoas espertas aquelas que disseram “Uou! Quanto código!”. Quando trabalhamos com propriedades nós deixamos os campos que contém informações visíveis somente dentro do tipo onde foram declarados e para utilizar essas informações são declarados dois métodos, sendo um para ler a informação e retornar seu valor e outro para gravar a informação. Veja no Exemplo 4 um exemplo de leitura e gravação de informação usando propriedades:

Exemplo 4

C#

[sourcecode language="csharp"]
class Program
{
static void Main(string[] args)
{
Carro Carro = new Carro(); //criando uma instância de carro
Carro.Cor = "Branco"; //gravando valor no campo Cor
Carro.Km = 10.000; //gravando valor no campo Km

System.Console.WriteLine("Meu carro é da cor " + Carro.Cor + " e está com " + Carro.Km + " quilometros rodados."); //Lendo os campos Cor e Km
}
}
[/sourcecode]

É possível criar propriedades que permitem somente a leitura, somente gravação ou leitura e gravação. Uma propriedade que permite leitura e gravação é declarada como mostrado no Exemplo 3. Propriedades somente leitura são declaradas sem o método set e propriedades somente gravação sem o método get como mostra o Exemplo 5.

Exemplo5:

C#

[sourcecode language="csharp"]
public class Carro
{
private string Cor
{
get {return Cor;}
set {Cor = value;}
}

private double Km
{
get {return Km;}
set { Km = value;}
}

private string Montadora //Propriedade somente leitura
{
get {return "Montadora Brasil";}
}

private string NumeroMotor //Propriedade somente gravação
{
set { NumeroMotor = value;}
}
}
 [/sourcecode]

Embora a segurança das informações seja a principal razão para se encapsular campos de informações de um tipo, existem outras. Por exemplo, suponha que você queira tratar a entrada de dados na classe Carro, veja no Exemplo 6 como poderia ser feito.

Exemplo 6:

C#

[sourcecode language="csharp"]
public class Carro
{
private string Cor
{
get {return Cor;}
set {Cor = value;}
}

private double Km
{
   get {return Km;}   
Set{
    if (Value < 0)
    {      throw new ArgumentOutOfRangeException("Quilometragem", "Não é permitido uma quilometragem negativa.");
    }
    Km = Value;
   }
}

private string Montadora
{
get {return "Montadora Brasil";}
}

private string NumeroMotor
{
set { NumeroMotor = value;}
}

}
[/sourcecode]

Dessa forma será verificado se o valor informado para a quilometragem é menor que zero, caso seja, retorne uma exception informando que o valor não é valido para essa propriedade.

De fato quando trabalhamos com propriedades temos diversas vantagens, porém, há também suas desvantagens. Uma delas é o aumento de código, se comparado ao uso de campos.  Mas, tenho uma boa notícia, essa forma de se trabalhar com propriedades é passado! Desde a versão 3.0 do C# um recurso chamado Automatic Properties foi inserido na linguagem. Veja a declaração de uma propriedade utilizando esse recurso no Exemplo 7:

Exemplo 7:

C#

[sourcecode language="csharp"]
public class Carro
{
public string Cor { get; set; } //Propriedade simples, sem tratamento, leitura e gravação

private double Km //propriedade com tratamento de entrada de informações. Leitura e gravação
{
get{return Km;}
set{
if (value < 0)
throw new ArgumentOutOfRangeException("Quilometragem inválida", "Não é permitido uma quilometragem negativa.");
Km = value;
}
}
public string Montadora { get { return "MontadoraBrasil"; } } //Propriedade somente Leitura
public string NumeroMotor { set; } //Propriedade somente gravação
}
[/sourcecode]

Agora sim, perfeito! Não precisamos mais declarar a variável interna e nem os métodos Get e Set quando não houver necessidade de tratamento de dados, tanto os métodos quanto a variável são gerenciados automaticamente pelo compilador. O Exemplo 7 também mostra como declarar propriedades somente leitura e somente gravação. Agora podemos tratar propriedades como se fossem campos.

As coisas boas não param no recurso Automatic properties. A partir do Visual Studio 2008 é possível utilizar um atalho para criar propriedades, basta digitar a palavra “prop”e teclar tab duas vezes, pronto a propriedade está criada e com o foco no tipo para que somente tenhamos que digita-lo e teclando tab novamente o foco vai para o nome da propriedade para que novamente só tenhamos que informar. Ao finalizar a declaração, tecle enter para que o curso pule de linha e possamos declarar uma nova propriedade.

É importante saber algumas informações sobre propriedades, são elas:

Utilizar propriedades é muito importante para manter as informações de um tipo mais seguras.

 Até o próximo post!

Referências

Propriedades (Guia de Programação em C#) - http://msdn.microsoft.com/pt-br/library/x9fsa0sw.aspx

Programação aplicada com Microsoft .Net Framework – Jeffrey Richter