Olá,
Hoje irei falar de um recurso bem interessante, trata-se dos indexadores, o indexador é um array inteligente, ele pode ser usado tanto em classes como estrutura. Iremos criar um pequeno form que irá atuar como uma agenda, iremos gravar Nome e Telefone e posteriormente iremos pesquisar tanto o Nome quanto o Telefone que inserimos, utilizando os indexadores.
Requisitos para o Exemplo: Neste nosso exemplo iremos usar o Visual Studio 2008 com Framework 3.5, caso não tenha instalado, efetue o download gratuitamente no seguinte site : http://www.microsoft.com/Express/
1- No Visual Studio, crie um novo projeto do tipo WPF Application, o nome da solução pode deixar como Indexer, o nome do projeto escolha AgendaTelefonica conforme imagem abaixo:

1- Novo Projeto
2- Dentro do Projeto Crie 3 arquivos do tipo Class, com os seguintes nomes :
-Agenda (Agenda.cs)
-Nome (Nome.cs)
-NumeroTelefone (NumeroTelefone.cs)
2- Estrutura do Projeto
3-) Abra o arquivo Nome.cs, a primeira alteração que iremos fazer é no construtor da classe, no construtor iremos definir um parâmetro de entrada, este valor irá preencher um campo da classe, conforme o código abaixo:
1: private string nome;
2: public Nome(string text)
3: {
4: this.nome = text;
5: }
Agora, vamos criar dentro desta classe a propriedade que terá seu modificador publico para que possamos acessar de fora mesma, vale ressaltar que esta propriedade será apenas leitura, por isso não iremos implementar o método set.
public string Texto
{
get { return this.nome; }
}
Para finalizar a implementação desta classe, iremos inserir mais 3 métodos sendo eles GetHashCode() e Equals() , conforme o código abaixo
1: public override int GetHashCode()
2: {
3: return this.nome.GetHashCode();
4: }
5: public override bool Equals(object outro)
6: {
7: return (outro is Nome) && Equals((Nome)outro);
8: }
9: public bool Equals(Nome outro)
10: {
11: return this.nome == outro.nome;
12: }
A função desta classe Nome será armazenar e buscar os nomes, o nome é fornecido para o construtor, a implementação dos métodos Equals e GetHashCode é devido a necessidade de comparar os nomes durante a pesquisa em um array de valores.
Mais informações sobre Equals e GetHashCode acesse :
Equals -> http://msdn.microsoft.com/pt-br/library/ms173147.aspx
GetHashCode -> http://msdn.microsoft.com/pt-br/library/system.object.gethashcode.aspx
Faça a mesma implementação da classe Nome para a Classe NumeroTelefones, conforme código abaixo:
1: class NumeroTelefones
2: {
3: public NumeroTelefones(string texto)
4: {
5: this.numero = texto;
6: }
7: public NumeroTelefones()
8: {
9:
10: }
11: public string Text
12: {
13: get { return this.numero; }
14: }
15:
16: public override int GetHashCode()
17: {
18: return this.numero.GetHashCode();
19: }
20:
21: public override bool Equals(object other)
22: {
23: return (other is NumeroTelefones) && Equals((NumeroTelefones)other);
24: }
25:
26: public bool Equals(NumeroTelefones other)
27: {
28: return this.numero == other.numero;
29: }
30:
31: private string numero;
32: }
Vamos abrir o arquivo Agenda.cs, dentro da classe agenda iremos implementar dois arrays privados: um array de valores para Nome e um array de valore para NumeroTelefones, conforme código abaixo:
1: private int tamanhoAtualIndice;
2: private Nome[] nomes;
3: private NumeroTelefones[] telefones;
No construtor da classe iremos instanciar e inicializar as variáveis declaradas acima:
1: //Definindo o Construtor da Classe Agenda
2: public Agenda()
3: {
4: this.tamanhoAtualIndice = 0;
5: this.nomes = new Nome[0];
6: this.telefones = new NumeroTelefones[0];
7: }
Criaremos um método que irá inserir os valores dentro de um Index das classes Nome e NumeroTelefones, veja o exemplo abaixo, repare que estamos acessando o índex do nome pela notação de colchetes. A sintaxe que utilizamos em um indexador é bem parecida com a de um array, no entando, existem algumas diferença, tais como:
- Os indexadores sofrem sobrecarga (overload) já os arrays não.
- Os indexadores podem utilizar subscritos não numéricos, como string, object e etc, enquanto os arrays só podem utilizar subscritos inteiros.
1: public void Add(Nome nome, NumeroTelefones numero)
2: {
3: aumentarArrays();
4: this.nomes[tamanhoAtualIndice] = nome;
5: this.telefones[tamanhoAtualIndice] = numero;
6: this.tamanhoAtualIndice++;
7: }
No código acima, estamos chamando o método aumentarArrays(em breve iremos falar deste), e estamos usando a variável tamanhoAtualIndice dentro dos índices dos campos nomes e telefones.
Criando o método aumentarArrays; Este método será chamado por Add para verificar se os arrays estão cheios quando o usuário adiciona um outro valor, ele cria dois novos arrays maiores copia o valor para eles e então descarta os antigos, uma vez que para redimensionar um array precisamos copiar os elementos para um novo array, copiar os elementos (omitir alguns se o novo array for menor) e então atualizar qualquer referência ao array original para que ela se refira ao novo array, isso poderia ser resolvido com outras estruturas de coleções como ArrayList e etc., porém não é o intuito deste artigo falar sobre.
1: private void aumentarArrays()
2: {
3: if (this.tamanhoAtualIndice == this.nomes.Length)
4: {
5: int aumentarIndice = tamanhoAtualIndice + 16;
6: Nome[] maisNomes = new Nome[aumentarIndice];
7: this.nomes.CopyTo(maisNomes, 0);
8: NumeroTelefones[] maisTelefones = new NumeroTelefones[aumentarIndice];
9: this.telefones.CopyTo(maisTelefones, 0);
10: this.nomes = maisNomes;
11: this.telefones = maisTelefones;
12: }
13: }
Agora vamos à implementação dos indexadores, lembrando que um indexador não é um método por isso não há parênteses contendo parâmetros, mas há colchetes que especificam um índice. Esse índice é utilizado para especificar que elemento está sendo acessado. Todos os indexadores utilizam a palavra-chave this no lugar do nome e vale a pena falar que em uma classe ou estrutura podemos definir no máximo um indexador.
Com base nas informações acima, vamos declarar o indexador da classe Nome, veja o código abaixo:
1: public Nome this[NumeroTelefones numero]
2: {
3: get
4: {
5: int i = Array.IndexOf(this.telefones, numero);
6: if (i != -1)
7: return this.nomes[i];
8: else
9: return new Nome();
10: }
11: }
O método de acesso get do Indexador da Classe Nome possui a finalidade de localizar o nome que corresponde ao número de telefone especificado na consulta. Para fazer isso estamos usando o método IndexOf da classe Array. O método IndexOf executa uma pesquisa em um array, retornando o índice do primeiro item no array correspondente a pesquisa. O primeiro argumento para IndexOf é o array a ser pesquisado (telefones),já o segundo argumento é o item que estou pesquisando, o IndexOf retorna o índice inteiro do elemento se ele o encontrar; caso contrário, IndexOf retorna -1. Se o indexador encontrar o número de telefone, ele deve retorná-lo; caso contrário ele deve retornar um nome vazio.
Vamos fazer a mesma coisa com Telefone:
1: public NumeroTelefones this[Nome nome]
2: {
3: get
4: {
5: int i = Array.IndexOf(this.nomes, nome);
6: if (i != -1)
7: return this.telefones[i];
8: else
9: return new NumeroTelefones();
10: }
11: }
Agora já terminamos de fazer nosso código, a classe Agenda deverá ficar da seguinte maneira:
1: class Agenda
2: {
3: private int tamanhoAtualIndice;
4: private Nome[] nomes;
5: private NumeroTelefones[] telefones;
6:
7: //Definindo o Construtor da Classe Agenda
8: public Agenda()
9: {
10: this.tamanhoAtualIndice = 0;
11: this.nomes = new Nome[0];
12: this.telefones = new NumeroTelefones[0];
13: }
14:
15: public void Add(Nome nome, NumeroTelefones numero)
16: {
17: aumentarArrays();
18: this.nomes[tamanhoAtualIndice] = nome;
19: this.telefones[tamanhoAtualIndice] = numero;
20: this.tamanhoAtualIndice++;
21: }
22: public Nome this[NumeroTelefones numero]
23: {
24: get
25: {
26: int i = Array.IndexOf(this.telefones, numero);
27: if (i != -1)
28: return this.nomes[i];
29: else
30: return new Nome();
31: }
32: }
33:
34: public NumeroTelefones this[Nome nome]
35: {
36: get
37: {
38: int i = Array.IndexOf(this.nomes, nome);
39: if (i != -1)
40: return this.telefones[i];
41: else
42: return new NumeroTelefones();
43: }
44: }
45:
46: private void aumentarArrays()
47: {
48: if (this.tamanhoAtualIndice == this.nomes.Length)
49: {
50: int aumentarIndice = tamanhoAtualIndice + 16;
51:
52: Nome[] maisNomes = new Nome[aumentarIndice];
53: this.nomes.CopyTo(maisNomes, 0);
54:
55: NumeroTelefones[] maisTelefones = new NumeroTelefones[aumentarIndice];
56: this.telefones.CopyTo(maisTelefones, 0);
57:
58: this.nomes = maisNomes;
59: this.telefones = maisTelefones;
60: }
61: }
62:
63:
64: }
Finalizamos nosso código iremos criar um pequeno formulário para efetuar os testes.
1-) Abra o arquivo Windows1.xaml e insira os controles abaixo:
|
Controle
|
Propriedades
|
Observação
|
|
TextBox
|
- Altere a propriedade ID do controle para “nomeTextBox”;
|
É importante sempre que inserir um controle na pagina um nome simples e objetivo para que o mesmo possa ser localizado facilmente no código.
|
|
TextBox
|
- Altere a propriedade ID do controle para “telefoneTextBox”;
|
|
|
Button
|
- Altere a propriedade ID do controle para “addButton”;
|
Este será o botão responsável por disparar o evento que irá adicionar os valores das texbox dentro da array.
|
|
Button
|
- Altere a propriedade ID do controle para “pesqTelefoneTextBox”;
|
Este será o botão responsável por disparar o evento que irá efetuar as pesquisas por telefone.
|
|
Button
|
- Altere a propriedade ID do controle para “pesqNomeTextBox”;
|
Este será o botão responsável por disparar o evento que irá efetuar as pesquisas por nome.
|
Alinhe os controles conforme a imagem abaixo:
Dê um duplo clique em cima do botão Add, o Visual Studio irá criar o evento Click do botão automaticamente, dentro deste evento insira o código abaixo:
1: private Agenda agenda = new Agenda();
2: private void addClick(object sender, RoutedEventArgs e)
3: {
4: if (!String.IsNullOrEmpty(name.Text) && !String.IsNullOrEmpty(phoneNumber.Text))
5: {
6: agenda.Add(new Nome(nomeTextBox.Text),
7: new NumeroTelefones(telefoneTextBox.Text));
8: nomeTextBox.Text = "";
9: telefoneTextBox.Text = "";
10: }
11: }
Faça o mesmo processo com pesqTelefoneButton;
1: private void pesqTelefoneButtonClick(object sender, RoutedEventArgs e)
2: {
3: string text = telefoneTextBox.Text;
4: if (!String.IsNullOrEmpty(text))
5: {
6: nomeTextBox.Text = agenda[new NumeroTelefones(text)].Texto;
7: }
8: }
Dê um clique duplo em cima do botão pesqNomeButton, e insira o código abaixo:
1: private void pesqNomeButtonClick(object sender, RoutedEventArgs e)
2: {
3: string text = nomeTextBox.Text;
4: if (!String.IsNullOrEmpty(text))
5: {
6: telefoneTextBox.Text = agenda[new Nome(text)].Text;
7: }
8: }
Já podemos efetuar os testes, compile a aplicação e veja se a mesma irá ocorrer erros, caso não ocorra nenhum erro, execute a aplicação e efetue os seguintes testes:
1-) Digite um nome e um telefone e clique em adicionar;
2-) Vá na textBox do Nome e digite o nome que você acabou de adicionar e clique em pesquisar Nome, você verá que o textBox do telefone irá preencher automaticamente.
Por enquanto é isso, nos vemos na próxima, abraço.
Mais informações sobre indexadores:
- http://msdn.microsoft.com/pt-br/library/6×16t2tx.aspx
- http://www.csharphelp.com/archives/archive140.html
Comentários