Indizadores

Concepto de indizador

    Un indizador es una definición de cómo se puede aplicar el operador de acceso a tablas ([ ]) a los objetos de un tipo de dato. Esto es especialmente útil para hacer más clara la sintaxis de acceso a elementos de objetos que puedan contener colecciones de elementos, pues permite tratarlos como si fuesen tablas normales.

    Los indizadores permiten definir código a ejecutar cada vez que se acceda a un objeto del tipo del que son miembros usando la sintaxis propia de las tablas, ya sea para leer o escribir. A diferencia de las tablas, los índices que se les pase entre corchetes no tiene porqué ser enteros, pudiéndose definir varios indizadores en un mismo tipo siempre y cuando cada uno tome un número o tipo de índices diferente.

Definición de indizador

A la hora de definir un indizador se usa una sintaxis parecida a la de las propiedades:


<tipoIndizador> this[<índices>]
{
 set
 {
  <códigoEscritura>
 }
 
 get
 {
  <códigoLectura>
 }
}

    Las únicas diferencias entre esta sintaxis y la de las propiedades son:

  • El nombre dado a un indizador siempre ha de ser this, pues carece de sentido poder darle cualquiera en tanto que a un indizador no se accede por su nombre sino aplicando el operador [ ] a un objeto. Por ello, lo que diferenciará a unos indizadores de otros será el número y tipo de sus <índices>.

  • En <índices> se indica cuáles son los índices que se pueden usar al acceder al indizador. Para ello la sintaxis usada es casi la misma que la que se usa para especificar los parámetros de un método, sólo que no se admite la inclusión de modificadores ref, out o params y que siempre ha de definirse al menos un parámetro. Obviamente, el nombre que se dé a cada índice será el nombre con el que luego se podrá acceder al mismo en los bloques set/get.

  • No se pueden definir indizadores estáticos, sino sólo indizadores de objetos.

    Por todo lo demás, la sintaxis de definición de los indizadores es la misma que la de las propiedades: pueden ser de sólo lectura o de sólo escritura, da igual el orden en que se definan sus bloques set/get, dentro del bloque set se puede acceder al valor a escribir a través del parámetro especial value del tipo del indizador, el código del bloque get ha de devolver un objeto de dicho tipo, etc.                                                                                                                    

    A continuación se muestra un ejemplo de definición de una clase que consta de dos indizadores: ambos permiten almacenar elementos de tipo entero, pero uno toma como índice un entero y el otro toma dos cadenas:

 
 using System;
 
 public class A
 {
  public int this[int índice]
  {
   set
   {
    Console.WriteLine("Escrito {0} en posición {1}", value, índice);
   }
   get
   {          
    Console.WriteLine("Leído 1 de posición {0}",  índice);
    return 1;
   }
  }
  
  public int this[string cad1, string cad2]
  {
   set
   {
    Console.WriteLine("Escrito {0} en posición ({1},{2})"
, value, cad1, cad2);
   }
   get
   {
    Console.WriteLine("Leído 2 de posición ({0},{1})", cad1, cad2);
    return 2;
   }
  }

Acceso a indizadores

    Para acceder a un indizador se utiliza exactamente la misma sintaxis que para acceder a una tabla, sólo que los índices no tienen porqué ser enteros sino que pueden ser de cualquier tipo de dato que se haya especificado en su definición. Por ejemplo, accesos válidos a los indizadores de un objeto de la clase A definida en el epígrafe anterior son:


A obj = new A();
obj[100] = obj["barco", "coche"];

    La ejecución de la asignación de este ejemplo producirá esta salida por pantalla:


Leído 2 de posición (barco, coche)

Escrito 2 en posición 100

Implementación interna de indizadores

    Al igual que las propiedades, para facilitar la interoperabilidad entre lenguajes los indizadores son también convertidos por el compilador en llamadas a métodos cuya definición se deduce de la definición del indizador. Ahora los métodos son de la forma:


<tipoIndizador> get_Item(<índices>)
{
    <códigoLectura>
}
void set_Item(<índices>, <tipoIndizador> value)
{
    <códigoEscritura>
}

    Nuevamente, hay que tener cuidado con la signatura de los métodos que se definan en una clase ya que como la de alguno coincida con la generada automáticamente por el compilador para los indizadores se producirá un error de ambigüedad.

Indizadores
José Antonio González Seco

José Antonio es experto en tecnologias Microsoft. Imparte cursos y conferencias en congresos sobre C# y .NET en Universidades de toda España (Sevilla, Barcelona, San Sebastián, Valencia, Oviedo, etc.) en representación de grandes empresas como Microsoft.
Fecha de alta:13/10/2006
Última actualizacion:13/10/2006
Visitas totales:16910
Valorar el contenido:
Últimas consultas realizadas en los foros
Últimas preguntas sin contestar en los foros de devjoker.com