Introducción a los Indexadores
Los indexadores representan un mceanismo fundamental en la programación orientada a objetos de C#, que permite tratar instancias de una clase de manera semejante a cómo se accede a un arreglo. Esta característica mejora la legibilidad del código, haciendo las operaciones de acceso y modificación de datos más intuitivas. A diferencia de las propiedades ordinarias, los indexadores requieren parámetros dentro de su declaración para identificar qué elemento específico está siendo consultado o modificado.
Sintaxis y Definición
A diferencia de las propiedades convencionales que utilizan identificadores explícitos, la definición de un indexador se realiza utilizando la palabra clave this. La sintaxis general incluye un tipo de retorno y el especificador de índice:
tipoDeRetorno this[indexTipo parametro]
{
get { /* lógica de obtención */ }
set { /* lógica de asignación */ }
}
Este constructo permite encadenar accesos mediante corchetes cuadrados. A continuación, se presenta un ejemplo funcional donde se encapsula una colección interna de cadenas, asegurando validaciones de rango antes de acceder a la memoria.
Ejemplo de Implementación Básica
En este caso, creamos una clase llamada GestorDatos que gestiona un array privado. El constructor inicializa el almacenamiento, mientras que el indexador controla la seguridad de los límites.
using System;
using System.Collections.Generic;
namespace BibliotecaDemo
{
public class GestorDatos
{
private int capacidadMaxima = 20;
private string[] almacenInternal = null;
public GestorDatos()
{
almacenInternal = new string[capacidadMaxima];
for (int x = 0; x < capacidadMaxima; x++)
{
almacenInternal[x] = "Vacío";
}
}
// Índice basado en enteros
public string this[int posicion]
{
get
{
string resultado = "";
if (posicion >= 0 && posicion < almacenInternal.Length)
{
resultado = almacenInternal[posicion];
}
return resultado;
}
set
{
if (posicion >= 0 && posicion < almacenInternal.Length)
{
almacenInternal[posicion] = value;
}
}
}
public static void Ejecutar()
{
var gestor = new GestorDatos();
// Asignación y visualización de valores
gestor[0] = "Primera entrada";
gestor[5] = "Quinta entrada";
Console.WriteLine(gestor[0]);
Console.WriteLine(gestor[5]);
}
}
}
Sobrecarga de Indexadores
Una ventaja considerable de los indexadores es la posibilidad de sobrecargarlos. Esto significa que una misma clase puede manejar múltiples firmas de indexadores simultáneamente, aceptando distintos tipos de parámetros (como enteros, cadenas u otros objetos). Cada sobrecarga debe ser única en términos de la secuencia y el tipo de sus parámetros.
El siguiente ejemplo demuestra un escenario donde coexisten dos indexadores: uno que utiliza un índice numérico entero y otro que busca elementos basándose en una cadena específica, retornando la posición encontrada.
using System;
using System.Linq;
namespace SobrecargaDemo
{
public class GestionMultiplex
{
private string[] registros = new string[15];
public GestionMultiplex()
{
Array.Fill(registros, "Sin Datos");
}
// Índice entero para acceso posicional
public string this[int idx]
{
get
{
return (idx >= 0 && idx < registros.Length) ? registros[idx] : "Índice inválido";
}
set
{
if (idx >= 0 && idx < registros.Length)
{
registros[idx] = value;
}
}
}
// Índice basado en cadena para búsqueda inversa
public int this[string valorBusqueda]
{
get
{
int ubicacionEncontrada = -1;
for (int k = 0; k < registros.Length; k++)
{
if (string.Equals(registros[k], valorBusqueda))
{
ubicacionEncontrada = k;
break;
}
}
return ubicacionEncontrada;
}
}
public static void Main()
{
var app = new GestionMultiplex();
app[10] = "Valor Objetivo";
// Uso del índice entero
Console.WriteLine("Acceso directo: {0}", app[10]);
// Uso del índice por texto (busca la posición)
int pos = app["Valor Objetivo"];
Console.WriteLine("Posición encontrada: {0}", pos);
}
}
}