Índices y rangos en C# 8 (1 de 2) - Code Variables -->
Code Variables Code Variables

Latest news

جاري التحميل ...

Índices y rangos en C# 8 (1 de 2)

.NET Core Seguimos analizando las novedades que traerá C# 8, y esta vez vamos a detenernos en una característica que aportará algo más de agilidad a la hora de trocear o acceder a elementos de arrays y algunos tipos de colecciones similares, como Span<T>.

Como muchas otras características del lenguaje, se trata de algunos azucarillos sintácticos creados en torno a dos nuevos tipos añadidos a las bibliotecas básicas del framework: las estructuras System.Index y System.Range. Por esta razón, para utilizar estos elementos no sólo es necesario disponer de nuevos compiladores, sino también de nuevas versiones del framework.
Recordad que a día de hoy ya se puede probar C# 8 en Visual Studio 2019 o directamente desde la interfaz de línea de comandos de .NET Core.

Índices de arrays con System.Index

Hasta esta versión de C#, la forma natural de acceder a un elemento específico de un array era indicando el entero que representaba su posición en el mismo. Por ejemplo, con arr[0] podíamos acceder al primer elemento de la colección, o con arr[arr.Length-1] al último.

La nueva estructura Index proporciona una fórmula para almacenar y gestionar índices usando tipos específicamente diseñados para ello, lo que permite añadir algo más de flexibilidad al resultado. Su uso básico, que no parece demasiado útil, es el siguiente:
var primes = new[] { 2, 3, 5, 7, 11, 13, 17, 19 };

Index i0 = new Index(0);
Index i1 = new Index(1);
Index i7 = new Index(7);

Console.WriteLine(primes[i0]); // 2
Console.WriteLine(primes[i1]); // 3
Console.WriteLine(primes[i7]); // 19
Así al vistazo no parece algo que valga demasiado la pena, ¿verdad? Bueno, pues como aportación interesante, a la hora de crear un índice podemos indicar si la referencia la hacemos desde el principio o desde el final de la secuencia:
var primes = new[] { 2, 3, 5, 7, 11, 13, 17, 19 };

Index fromStart3 = new Index(3); // Por defecto, 'fromEnd' es falso
Index fromEnd1 = new Index(1, fromEnd: true);
Index fromEnd8 = new Index(8, fromEnd: true);

Console.WriteLine(primes[fromStart3]); // 7
Console.WriteLine(primes[fromEnd1]); // 19
Console.WriteLine(primes[fromEnd8]); // 2
¡Alto ahí! Fijaos en un detalle sumamente importante: cuando comenzamos por el final, el índice 1 es el primer elemento. O en otras palabras, un acceso desde el final al índice 0 daría un error, porque este elemento sería posterior al último item de la colección; sin embargo, cuando contamos desde el principio, el índice cero es el primero.
var ceroFromStart = new Index(0);
var ceroFromEnd = new Index(0, fromEnd: true);
Console.WriteLine(primes[ceroFromStart]); // 2
Console.WriteLine(primes[ceroFromEnd]); // Error: IndexOutOfRangeException
Por último, cabe añadir que la estructura Index dispone de algunos métodos estáticos para agilizar la creación de índices, como Index.FromStart() o Index.FromEnd(), o para obtener referencias al comienzo y final (recordad, ¡fuera del array!) con Index.Start e Index.End respectivamente:
Index fromEnd3A = Index.FromEnd(3);
Index fromEnd3B = new Index(3, fromEnd: true);
Console.WriteLine(fromEnd3A.Equals(fromEnd3A)); // True

var start = Index.Start;
var alsoStart = Index.FromStart(0);
Console.WriteLine(start.Equals(alsoStart)); // True

Conversiones implícitas y el operador hat ^

Anteriormente hemos visto lo fácil que es crear índices y utilizarlos para acceder a los elementos de una colección. Pero, obviamente, esto no podía quedar ahí.

En primer lugar, el tipo Index dispone de conversiones implícitas hacia y desde int, lo que quiere decir que normalmente podremos utilizar estos dos tipos indistintamente, como se muestra en el siguiente ejemplo:
var primes = new[] { 2, 3, 5, 7, 11, 13, 17, 19 };
Index fromStart3a = new Index(3);
Index fromStart3b = 3;
int fromStart3c = 3;

Console.WriteLine(primes[fromStart3a]); // 7
Console.WriteLine(primes[fromStart3b]); // 7
Console.WriteLine(primes[fromStart3c]); // 7
Console.WriteLine(fromStart3a.Equals(fromStart3c)); // True
Vale, esto simplifica la codificación de índices comenzando por el principio, igual que lo hemos hecho siempre con enteros, pero, ¿qué ocurre con la indexación desde el final?

Y aquí es donde entra en juego el nuevo uso del operador hat (sombrero) ^ de C# 8. Este operador es un mero azucarillo sintáctico para facilitar la creación de índices desde el final, como hacíamos con Index.FromEnd(), pero de forma más compacta. Veamos unos ejemplos:
var primes = new[] { 2, 3, 5, 7, 11, 13, 17, 19 };
var fromEnd2A = Index.FromEnd(2);
var fromEnd2B = ^2; // = Index.FromEnd(2)

Console.WriteLine(primes[fromEnd2A] == primes[fromEnd2B]); // True
Console.WriteLine(primes[fromEnd2B]); // 17
En el siguiente post veremos cómo la nueva estructura Range permite especificar rangos o extraer porciones de colecciones indicando los límites superiores e inferiores, y cómo se vale de Index para ello.

Publicado en: www.variablenotfound.com.

Comments



If you like the content of our blog, we hope to stay in constant communication, just enter your email to subscribe to the blog's express mail to receive new blog updates, and you can send a message by clicking on the button next ...

إتصل بنا

About the site

author Code Variables  Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

Learn more ←

Blog visitors

Blog stats

All Copyrights Reserved

Code Variables

2019