Indexadores C#
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
4 Responses to “Indexadores C#”
Leave a Reply

zé on julho 7th, 2009
Olá…gostei muito desta explicação.. porque me vai ajudar um projecto que tenho a desenvolver, gostaria se fosse possível que me dessem umas dicas: tenho que fazer um calendário semestral de uma escola, em que posso definir e mudar os eventos(reuniões,workshops) ao longo de 20 semanas..bem como saber que um determinado evento aconteceu nessa hora,campos livres para possiveis marcações de outros eventos,, agradecia
Cumprimentos
Nelson Borges on julho 8th, 2009
Olá Zé,
Sim, apenas me diga qual a sua duvida ? Existe uma aplicação muito bacana (com o codigo fonte) no site do codeproject, veja se te ajuda -: > http://www.codeproject.com/KB/WPF/Quick_WPf_MonthView_Cal.aspx
Abraço,
zé on julho 11th, 2009
Obrigadíssimo,vai me ajudar com certeza, o objectivo era poder definir horários semanais e poder, procurar dias livres para criar novos eventos, o enunciado do problema é este:
http://www.4shared.com/file/115982560/b0eb2c85/educational_institution.html
poderia dar uma vista de olhos…
Cumprimentos
zé on julho 11th, 2009
Vi agora o codeproject que me enviou,, só que está em VB e eu cria para c# windows forms…