lunes, 14 de octubre de 2013

Indizadores en C#

Tabla de Contenido

0. Introducción
1. Indizadores en C#
2. Implementación de un Indizador
3. Sobrecarga de Indizadores
4. Implementación de un Indizador con Múltiples Parámetros
5. Representación Interna en CLR de un Indizador
6. Comentarios
7. Conclusiones
8. Glosario
9. Enlaces & Literatura

0. Introducción

Veremos en este artículo cómo los indizadores se convierten en un medio natural de acceso a elementos de una clase, estructura o interfaz de forma intuitiva. También reconoceremos su utilidad, cómo implementarlos, algunos comentarios acerca de su existencia en el lenguaje C#, cómo sobrecargar un indizador, la implementación de indizadores con múltiples parámetros, finalmente cómo el compilador genera los indizadores para la CLR.

1. Indizadores en C#

En el día a día del programador es muy probable haya tenido que manipular una cadena de caracteres (string) para acceder a uno de los elementos (objeto Char [2]) del arreglo; como en:

string nombre = "Valentina";
Console.WriteLine (nombre[0]); // 'V'
Console.WriteLine (nombre[5]); // 't'

Aquí se evidencia el uso de un indizador en la clase string [3] .

De acuardo con [1]: los indizadores son un mecanismo natural e intuitivo para acceder a elementos de una clase o estructura como podrían ser un arreglo, una lista o un diccionario de valores. Y si nos fíjamos en el ejemplo de código fuente anterior, con la expresión nombre[0] estamos significando el acceso a un elemento de una lista o arreglo indicando el identificador (nombre) y el índice (0).

Hay que agregar que el uso de los indizadores es similar al de los arreglos, sólo que la diferencia reside en que el tipo del índice puede ser cualquier otro tipo de dato (char, byte, float, double, decimal, o cualquier otra estructura compleja).

En línea con las propiedades, los indizadores tienen las mismos modificadores (ver Figura 1).
Figura. Modificadores de Indizadores [1].
[Nota: En experiencia pasada es posible que nos refiriéramos a un objeto string como un arreglo, cuando en C# no es así, porque internamente esta clase tiene un campo miembro que consiste en un arreglo de objetos Char.]

2. Implementación de un Indizador

A continuación voy a crear una clase llamada Frase. Esta clase tendrá un indizador que permita acceder a cada uno de los términos de una frase almacenados en un arreglo de objetos string.

Archivo C# Frase.cs [enlace alternativo]:
Obervemos la línea 5: se declara un arreglo de objetos string a partir de la frase "GitHub Gist permite crear fragmentos de código de forma eficiente.". Más adelante, en las líneas 7-17 se crea el indizador siguiendo esta sintaxis básica de declaración:

public int this[int indice] // Declaración de índice
{
// construcciones de acceso set y get
}

El indizador declarado en la clase Frase permite acceder a los elementos del arreglo de objetos string (el cual corresponde con un campo de instancia). [Nota: como el indizador está asociado con la clase después del tipo de dato de valor de retorno se usa la palabra clave this].

En el mismo archivo se incluye el código cliente en el método Main. Aquí básicamente creamos una instancia de Frase (línea 21), luego en la línea 22 a través del indizador se obtiene la palabra Gist del arreglo palabras.

► Prueba de ejecución.

3. Sobrecarga de Indizadores

Veamos el siguiente ejemplo para demostrar la sobrecarga de indizadores.

En la clase SobrecargaIndizador hay dos declaraciones de indizadores. Son las que siguen:

public string this[int indice]

public string this[string dato]

En la primera versión está permitido pasar un argumento de tipo int. La función básica de este indizador es permitir asignar y recuperar valores del arreglo Datos a través de la especificación de la posición para las operaciones de acceso.

Por otro lado, la segunda versión permite asignar y recuperar un dato sobre el arreglo Datos especificando un objeto string como índice.

El archivo SobrecargaIndizador.cs incluye código cliente de prueba del uso de indizadores sobrecargados.

► Prueba de ejecución.

4. Implementación de un Indizador con Múltiples Parámetros

Para usar un indizador con múltiples parámetros se sigue esta sintaxis:

public string this [int param1, string param2]
{
set { ... }
get { ... }
}

Tenga en cuenta que los parámetros pueden ser de distinto tipo de dato. En caso de que se omita la construcción de acceso set, al igual que las propiedades, el indizador será de sólo lectura.

5. Representación Interna en la CLR de un Indizador

El compilador de C# se encarga de represantar los indizadores con métodos de las forma:
  • get_Elemento
  • set_Elemento
Concretamente para el ejemplo de la clase Frase, tenemos:

public string get_Elemento (int indicePalabra) { ... }

public void set_Elemento (int IndicePalabra, string value) { ... }

6. Comentarios

Algunos comentarios presentandos en [4]:
  • El tipo de un indizador y el tipo de sus parámetros deben ser por lo menos tan accesibles como el propio indizador.
  • Los indizadores también pueden ser utilizados en interfaces [5].
  • La firma de un indizador está formada por el ´número de parámetros formales y sus tipos. No incluye el tipo de indizador ni lso nombres de los parámetros formales. Si se declara más de un indizador en una misma clase, cada indizador deberá tener una firma diferente.
  • Los valores de un indizador no se clasifican como variables; por ello, no es posible transferir un valor del indizador como un parámetro ref u out.

7. Conclusiones

Hemos tenido la oportunidad de explorar los indizadores (o en inglés, indexers) que nos permiten acceder a un elemento de un campo de instancia en forma de arreglo, lista, o diccionario. Aprendimos que es posible acceder a un elemento de cualquiera de las estructuras mencionadas especificando el identificador de un tipo y a continuación el índice (el cual podría tratarse de cualquier tipo de dato).

8. Glosario

  • Indizador
  • Índice

9. Enlaces & Literatura

[1]: C# 5.0 in a Nutshell by Joseph Albahari and Ben Albahari. Copyright 2012 Joseph Albahari and Ben Albahari, 978-1-449-32010-2.
[2]: Char Structure (System) - http://msdn.microsoft.com/en-us/library/system.char.aspx
[3]: string (C# Reference) - http://msdn.microsoft.com/en-us/library/vstudio/362314fe.aspx
[4]: Utilizar indizadores (Guía de programación de C#) - http://msdn.microsoft.com/es-es/library/2549tw02(v=vs.90).aspx
[5]: Indizadores en interfaces (Guía de programación de C#) - http://msdn.microsoft.com/es-es/library/tkyhsw31(v=vs.90).aspx


O

No hay comentarios:

Publicar un comentario

Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.