Aprenda a administrar colecciones de datos mediante List<T> en C#

En este tutorial de presentación se proporciona una introducción al lenguaje C# y se exponen los conceptos básicos de la clase List<T>.

Requisitos previos

En el tutorial se espera que tenga una máquina configurada para el desarrollo local. Consulte Configuración del entorno local para obtener instrucciones de instalación e información general sobre el desarrollo de aplicaciones en .NET.

Si prefiere ejecutar el código sin tener que configurar un entorno local, consulte la versión interactiva en el explorador de este tutorial.

Un ejemplo de lista básico

Cree un directorio denominado list-tutorial. Conviértalo en el directorio actual y ejecute dotnet new console.

Importante

Las plantillas de C# para .NET 6 usan instrucciones de nivel superior. Es posible que la aplicación no coincida con el código de este artículo si ya ha actualizado a .NET 6. Para obtener más información, consulte el artículo Las nuevas plantillas de C# generan instrucciones de nivel superior.

El SDK de .NET 6 también agrega un conjunto de directivas implícitasglobal using para proyectos que usan los SDK siguientes:

  • Microsoft.NET.Sdk
  • Microsoft.NET.Sdk.Web
  • Microsoft.NET.Sdk.Worker

Estas directivas de global using implícitas incluyen los espacios de nombres más comunes para el tipo de proyecto.

Para saber más, consulte el artículo sobre las directivas de uso implícito

Abra Program.cs en su editor favorito y reemplace el código existente por el siguiente:

List<string> names = ["<name>", "Ana", "Felipe"];
foreach (var name in names)
{
    Console.WriteLine($"Hello {name.ToUpper()}!");
}

Reemplace <name> por su propio nombre. Guarde Program.cs. Escriba dotnet run en la ventana de la consola para probarlo.

Ha creado una lista de cadenas, ha agregado tres nombres a esa lista y ha impreso los nombres en MAYÚSCULAS. Los conceptos aplicados ya se han aprendido en los tutoriales anteriores para recorrer en bucle la lista.

El código para mostrar los nombres usa la característica interpolación de cadenas. Si un valor de string va precedido del carácter $, significa que puede insertar código de C# en la declaración de cadena. La cadena real reemplaza a ese código de C# con el valor que genera. En este ejemplo, reemplaza {name.ToUpper()} con cada nombre, convertido a mayúsculas, porque se llama al método ToUpper.

Vamos a continuar indagando.

Modificación del contenido de las listas

La colección creada usa el tipo List<T>. Este tipo almacena las secuencias de elementos. Especifique el tipo de los elementos entre corchetes angulares.

Un aspecto importante de este tipo List<T> es que se puede aumentar o reducir, lo que permite agregar o quitar elementos. Agregue este código al final del programa:

Console.WriteLine();
names.Add("Maria");
names.Add("Bill");
names.Remove("Ana");
foreach (var name in names)
{
    Console.WriteLine($"Hello {name.ToUpper()}!");
}

Se han agregado dos nombres más al final de la lista. También se ha quitado uno. Guarde el archivo y escriba dotnet run para probarlo.

List<T> también permite hacer referencia a elementos individuales a través del índice. Coloque el índice entre los tokens [ y ] después del nombre de la lista. C# utiliza 0 para el primer índice. Agregue este código directamente después del código que acaba de agregar y pruébelo:

Console.WriteLine($"My name is {names[0]}");
Console.WriteLine($"I've added {names[2]} and {names[3]} to the list");

No se puede acceder a un índice si se coloca después del final de la lista. Recuerde que los índices empiezan en 0, por lo que el índice más grande válido es uno menos que el número de elementos de la lista. Puede comprobar durante cuánto tiempo la lista usa la propiedad Count. Agregue el código siguiente al final del programa:

Console.WriteLine($"The list has {names.Count} people in it");

Guarde el archivo y vuelva a escribir dotnet run para ver los resultados.

Búsqueda y orden en las listas

En los ejemplos se usan listas relativamente pequeñas, pero las aplicaciones a menudo pueden crear listas que contengan muchos más elementos, en ocasiones, con una numeración que engloba millares. Para encontrar elementos en estas colecciones más grandes, debe buscar diferentes elementos en la lista. El método IndexOf busca un elemento y devuelve su índice. Si el elemento no está en la lista, IndexOf devuelve -1. Agregue este código a la parte inferior del programa:

var index = names.IndexOf("Felipe");
if (index == -1)
{
    Console.WriteLine($"When an item is not found, IndexOf returns {index}");
}
else
{
    Console.WriteLine($"The name {names[index]} is at index {index}");
}

index = names.IndexOf("Not Found");
if (index == -1)
{
    Console.WriteLine($"When an item is not found, IndexOf returns {index}");
}
else
{
    Console.WriteLine($"The name {names[index]} is at index {index}");

}

Los elementos de la lista también se pueden ordenar. El método Sort clasifica todos los elementos de la lista en su orden normal (por orden alfabético si se trata de cadenas). Agregue este código a la parte inferior del programa:

names.Sort();
foreach (var name in names)
{
    Console.WriteLine($"Hello {name.ToUpper()}!");
}

Guarde el archivo y escriba dotnet run para probar esta última versión.

Antes comenzar con la siguiente sección, se va a mover el código actual a un método independiente. Con este paso, resulta más fácil empezar con un nuevo ejemplo. Coloque todo el código que ha escrito en un nuevo método denominado WorkWithStrings(). Llame a ese método en la parte superior del programa. Cuando termine, el código debe tener un aspecto similar al siguiente:

WorkWithStrings();

void WorkWithStrings()
{
    List<string> names = ["<name>", "Ana", "Felipe"];
    foreach (var name in names)
    {
        Console.WriteLine($"Hello {name.ToUpper()}!");
    }

    Console.WriteLine();
    names.Add("Maria");
    names.Add("Bill");
    names.Remove("Ana");
    foreach (var name in names)
    {
        Console.WriteLine($"Hello {name.ToUpper()}!");
    }

    Console.WriteLine($"My name is {names[0]}");
    Console.WriteLine($"I've added {names[2]} and {names[3]} to the list");

    Console.WriteLine($"The list has {names.Count} people in it");

    var index = names.IndexOf("Felipe");
    if (index == -1)
    {
        Console.WriteLine($"When an item is not found, IndexOf returns {index}");
    }
    else
    {
        Console.WriteLine($"The name {names[index]} is at index {index}");
    }

    index = names.IndexOf("Not Found");
    if (index == -1)
    {
        Console.WriteLine($"When an item is not found, IndexOf returns {index}");
    }
    else
    {
        Console.WriteLine($"The name {names[index]} is at index {index}");

    }

    names.Sort();
    foreach (var name in names)
    {
        Console.WriteLine($"Hello {name.ToUpper()}!");
    }
}

Listas de otros tipos

Hasta el momento, se ha usado el tipo string en las listas. Se va a crear una lista List<T> con un tipo distinto. Se va a crear una serie de números.

Agregue lo siguiente al programa después de llamar a WorkWithStrings():

List<int> fibonacciNumbers = [1, 1];

Se crea una lista de enteros y se definen los dos primeros enteros con el valor 1. Son los dos primeros valores de una sucesión de Fibonacci, una secuencia de números. Cada número sucesivo de Fibonacci se obtiene con la suma de los dos números anteriores. Agregue este código:

var previous = fibonacciNumbers[fibonacciNumbers.Count - 1];
var previous2 = fibonacciNumbers[fibonacciNumbers.Count - 2];

fibonacciNumbers.Add(previous + previous2);

foreach (var item in fibonacciNumbers)
{
    Console.WriteLine(item);
}

Guarde el archivo y escriba dotnet run para ver los resultados.

Sugerencia

Para centrarse solo en esta sección, puede comentar el código que llama a WorkWithStrings();. Solo debe colocar dos caracteres / delante de la llamada, como en: // WorkWithStrings();.

Desafío

Trate de recopilar los conceptos que ha aprendido en esta lección y en las anteriores. Amplíe lo que ha creado hasta el momento con los números de Fibonacci. Pruebe a escribir el código para generar los veinte primeros números de la secuencia. (Como sugerencia, el 20º número de la serie de Fibonacci es 6765).

Desafío completo

Puede ver un ejemplo de solución en el ejemplo de código terminado en GitHub.

Con cada iteración del bucle, se obtienen los dos últimos enteros de la lista, se suman y se agrega el valor resultante a la lista. El bucle se repite hasta que se hayan agregado veinte elementos a la lista.

Enhorabuena, ha completado el tutorial sobre las listas. Puede seguir estos tutoriales adicionales en su propio entorno de desarrollo.

Puede obtener más información sobre cómo trabajar con el tipo List en el artículo de los aspectos básicos de .NET que trata sobre las colecciones. Ahí también podrá conocer muchos otros tipos de colecciones.