Saltar al pie de página
Iron Academy Logo
Aprender C#
Aprender C#

Otras categorías

Generación de números aleatorios en C#

Tim Corey
10m 05s

Generar números aleatorios en C# parece que debería ser una instrucción de una sola línea, y en muchos casos lo es. Pero el lenguaje ofrece más de una manera de producir valores aleatorios, y las diferencias entre ellos importan una vez que se toma en cuenta la seguridad de hilos, la reproducibilidad y el caso de uso. Elegir el enfoque incorrecto puede introducir errores sutiles en el código multihilo o hacer que un defecto reportado sea imposible de reproducir.

En su video "Generar números aleatorios en C#", Tim Corey repasa la clase clásica Random, explica por qué existen los valores de semilla e introduce Random.Shared como el valor predeterminado moderno. Cubriremos cada enfoque junto con el razonamiento detrás de él, para que pueda elegir el correcto sin adivinanzas. Si alguna vez se ha preguntado por qué hay múltiples caminos para algo que suena tan simple, este artículo lo desglosa.

Configurando la Demostración

[0:11 - 0:59] Tim trabaja dentro de una aplicación de consola en ejecución en Visual Studio 2026 (actualmente en vista previa) con .NET 10. Indica que todo lo demostrado aquí se aplica igualmente a .NET 9 y Visual Studio 2022, para que pueda seguir con las herramientas que ya tenga instaladas.

El diseño de demostración es un bucle for que imprime dos valores aleatorios lado a lado en cada iteración. Tener dos salidas ejecutándose en paralelo facilita observar si ambos generadores se comportan de manera independiente o producen resultados coincidentes, una distinción que se vuelve importante una vez que los valores de semilla entran en escena.

La Clase Clásica Random

[0:59 - 3:28] El enfoque original para generar enteros aleatorios en C# implica crear una instancia de la clase Random:

Random rng1 = new Random();
Random rng2 = new Random();
Random rng1 = new Random();
Random rng2 = new Random();

Cada instancia mantiene su propio estado interno. Llamar a .Next(1, 101) en cualquiera de ellas produce un entero entre 1 y 100. Tim destaca un detalle que confunde a los recién llegados: el valor mínimo es inclusivo, pero el máximo es exclusivo. Si quieres valores del 1 al 100, debes pasar 1 y 101, no 1 ni 100.

int output1 = rng1.Next(1, 101);
int output2 = rng2.Next(1, 101);
int output1 = rng1.Next(1, 101);
int output2 = rng2.Next(1, 101);

Ejecutar la aplicación confirma que ambas instancias producen diferentes secuencias. Ese resultado se siente intuitivo, pero lo que sucede cuando ambas instancias comparten el mismo punto de partida cuenta una historia diferente.

Un aviso importante sobre este enfoque: las instancias Random individuales no son seguras para el manejo de hilos. Si su aplicación realiza procesamiento paralelo y múltiples hilos acceden a la misma instancia, el estado interno puede dañarse, produciendo ceros o valores repetidos. La práctica segura es crear una instancia por hilo. Esa restricción es una de las razones por las que el lenguaje introdujo más tarde una mejor alternativa.

Valores de Semilla y Secuencias Reproducibles

[3:28 - 6:00] Tim luego pasa una semilla explícita a ambos constructores:

Random rng1 = new Random(25);
Random rng2 = new Random(25);
Random rng1 = new Random(25);
Random rng2 = new Random(25);

La salida cambia dramáticamente. Ambos generadores ahora producen secuencias idénticas: 79, 16, 25, 90, 50, 41, y así sucesivamente. Los números aún son individualmente impredecibles si no conoce la semilla, pero dado el mismo valor inicial, la progresión es determinista.

¿Por qué alguien querría eso? Tim da un ejemplo práctico. Imagine un juego que genera eventos aleatorios a lo largo de una sesión. Un jugador informa un error, pero reproducirlo parece imposible porque los resultados fueron aleatorizados. Si el juego registra la semilla utilizada para esa sesión, un desarrollador puede recrear la cadena exacta de decisiones inicializando una nueva instancia de Random con el mismo valor. La misma lógica se aplica a escenarios de pruebas unitarias donde necesita salidas consistentes para escribir afirmaciones confiables contra un comportamiento aleatorio.

Las instancias con semilla le dan aleatoriedad controlada: una secuencia que parece impredecible pero que se puede reproducir bajo demanda. Esa capacidad es la razón por la que el constructor clásico Random que acepta una semilla no ha sido obsoleto, incluso aunque ahora existe una API más simple.

Random.Shared: El Valor Predeterminado Moderno

[7:36 - 9:01] Comenzando con .NET 6, el enfoque recomendado para la mayoría de las generaciones de números aleatorios es Random.Shared:

int output1 = Random.Shared.Next(1, 101);
int output2 = Random.Shared.Next(1, 101);
int output1 = Random.Shared.Next(1, 101);
int output2 = Random.Shared.Next(1, 101);

No hay ninguna instancia involucrada. Random.Shared es una instancia estática segura para hilos gestionada por el tiempo de ejecución. Llamas a .Next() (o cualquiera de los otros métodos en la clase Random) y recibes un valor sin preocuparte por la duración del objeto o la concurrencia.

Tim ejecuta la demostración dos veces para demostrar el punto. La primera ejecución comienza con 94 y 91; el segundo comienza con 42 y 70. A diferencia de una instancia con semilla, Random.Shared se origina desde un estado inicial diferente cada vez que se inicia el proceso. No puede establecer una semilla, lo que significa que no puede producir una secuencia reproducible a través de esta API. Ese es el intercambio: simplicidad y seguridad a cambio de renunciar a la reproducción determinística.

Más allá de .Next(), Random.Shared expone métodos para generar dobles, llenar matrices de bytes y mezclar colecciones. Para la gran mayoría del código de aplicación donde necesita un valor aleatorio rápido sin ceremonia, esta única propiedad estática reemplaza el trabajo preliminar de manejar sus propias instancias.

Escogiendo el Enfoque Correcto

[9:01 - 9:30] Tim cierra con un marco de decisión conciso. Para aleatoriedad cotidiana (elegir un valor, mezclar una lista, seleccionar un elemento aleatorio), Random.Shared es la elección correcta. No requiere configuración, maneja la concurrencia y se comporta correctamente a través de hilos.

Cuando necesitas una serie repetible de salidas, ya sea para depuración, pruebas o repetición de simulaciones, crea una instancia Random dedicada con una semilla conocida. Tenga en cuenta que esas instancias no son seguras para compartir entre hilos.

Y para cualquier cosa que involucre seguridad (tokens, claves, sales de contraseñas), ninguno de los enfoques es apropiado. Tim dirige a los espectadores a las bibliotecas criptográficas en System.Security.Cryptography, que producen valores que no solo son aleatorios, sino también resistentes a la predicción.

Conclusión: API Simple, Diferencias Significativas

[9:30 - 9:50] Lo que hace que este tema sea engañoso es lo poco de código que se necesita. Una sola línea puede producir un número aleatorio a través de cualquiera de estos enfoques. La complejidad no está en la sintaxis sino en comprender qué garantías proporciona cada método: seguridad de hilos, reproducibilidad o fortaleza criptográfica.

Conclusión

[9:50 - 10:05] Para recapitular: Random.Shared cubre la mayoría de las necesidades sin necesidad de configuración y con seguridad de hilos incorporada. Las instancias Random con semilla te permiten reproducir una secuencia específica cuando la depuración o las pruebas lo requieren. Los generadores criptográficos pertenecen al código sensible a la seguridad donde la previsibilidad es una vulnerabilidad, no una característica.

La próxima vez que busque un número aleatorio en C#, la decisión se reduce a una pregunta: ¿necesita reproducir esta secuencia más tarde? Si la respuesta es no, Random.Shared es todo lo que necesitas.

Consejo de ejemplo: Al llamar a Random.Shared.Next(min, max), ten en cuenta que max es exclusivo. Un rango de 1 a 100 requiere pasar 1 y 101. Este límite de uno por uno también se aplica a las instancias con semilla.

Vea el video completo en su Canal de YouTube y obtenga más información sobre los fundamentos de C#.

Hero Worlddot related to Generación de números aleatorios en C#
Hero Affiliate related to Generación de números aleatorios en C#

Gana más compartiendo lo que te gusta

¿Creas contenidos para desarrolladores que trabajan con .NET, C#, Java, Python o Node.js? ¡Convierte tu experiencia en un ingreso extra!

Equipo de soporte de Iron

Estamos disponibles online las 24 horas, 5 días a la semana.
Chat
Email
Llámame