Novedades de C# 8: Índices y Rangos

Resumen de contenidos

Tiempo de lectura: 3 minutos
La imagen muestra el logotipo de c# 8.0

Ya son varias semanas hablando de C# 8, y hoy le toca el turno a los Índices y Rangos. En semanas anteriores hemos hablado sobre los Streams asíncronos o el nuevo pattern matching y su potencia, ahora es el momento de explorar que mejoras tenemos para operar colecciones.

Índices en C# 8

La primera de las dos opciones, los índices, nos va a permitir acceder al índice de una colección como su propio nombre indica. Vaya… ¿Esto es nuevo? Pues sí, la novedad es que se ha introducido una estructura «Index» dentro de «System.Index». Esta estructura nos va a permitir acceder a una posición desde el inicio (como toda la vida) o desde el final utilizando ‘^‘. Esta es precisamente la novedad con los índices. Imagina esta matriz:

var array = new string[]
{
    "Hola",
    "¿Cómo estás?",
    "Bien. ¿Y tú?",
    "Muy bien. Muchas gracias",
    "Adiós"
};

Hasta ahora, podíamos acceder a su índice simplemente haciendo algo como esto:

var primero = array[0];
var último = array[array.Lenght -1];

Utilizando índices, vamos a poder vamos a poder hacer algo como esto:

var indexPrimero = new Index(0);
var indexFin = new Index(1,true);
var primero = array[indexPrimero];
var último = array[indexFin];

Esto como tal es poco práctico, ya que estamos necesitando el doble de código, pero podemos colocar directamente el valor del índice:

var primero = array[0];
var último = array[^1];

Al trabajar con índices desde el final, hay que tener en cuenta que el símbolo ‘^’ es equivalente a la longitud del array, por lo que ‘^0’ provocará una excepción como lo haría acceder a ‘array.Lenght’

Rangos en C# 8

Hasta ahora los índices no nos están aportando especial utilidad, puesto que lo que conseguimos con ellos ya lo podíamos hacer con las herramientas que estaban disponibles. Donde van a tomar especial utilidad los índices de C# 8 es cuando los combinemos con los rangos.

Los rangos son una nueva estructura introducida en C# 8 que vamos a poder utilizar para extraer una parte de una colección. Para indicar que queremos usar un rango, vamos a poder utilizar la estructura «Range» dentro de «System.Range» o ‘..’. Si por ejemplo quisiéramos extraer las dos primeras posiciones del array, podemos hacer algo como esto:

var range = new Range(0, 2);
var sel = array[range];

var sel2 = array[0..2];

Es importante tener en cuenta que cuando definimos un rango con esta nueva característica de c# 8, el primer valor se incluye y el segundo se omite. Esto quiere decir que en el caso anterior, vamos a obtener las posiciones 0 y 1, omitiendo la dos.

Como realmente un rango esta compuesto por dos índices, vamos a poder utilizar un índice desde el final. Si por ejemplo queremos quedarnos con todos los valores menos el primero y el último, podemos hacer algo como esto:

var sel = array[1..^1];

Otra posibilidad que nos ofrecen los rangos es crear rangos abiertos:

var sel1 = array[..];       //Devuelve la colección completa
var sel2 = array[1..];      //Devuelve todos los valores desde el 1 hasta el final
var sel3 = array[..^1];    //Devuelve todos los valores desde el 0 hasta el penúltimo

¿Y dónde puedo aplicar esta nueva característica? La verdad es que no todas las colecciones implementan esta posibilidad, tienen que ser colecciones «contables» . Este tipo de colecciones contables engloban tipos como Array, List<T>, Span<T>,… y String (puedes verlos todos en el enlace anterior). Esto quiere decir que vamos a poder hacer un Substring.

var input = "Hola, buenos días";
var output = input[6..12]; //buenos

Conclusión

Esta característica de C# 8 para poder acceder a colecciones mediante índices y rangos puede aportar utilidad y legibilidad en el código, sobre todo a la hora de eliminar algunas operaciones con Linq que se limitan a obtener un fragmento secuencial de la colección. Es una herramienta built-in, por lo que vamos a tener mejor rendimiento que si usáramos Linq y es más compacto. ¿Qué te parece a ti esta característica?

En la próxima entrada acabaremos con las novedades hablando sobre las controvertidas interfaces de C#8.

Deja un comentario