Ir para o conteúdo do rodapé
Iron Academy Logo
Aprenda C#
Aprenda C#

Outras categorias

Gerando Números Aleatórios em C#

Tim Corey
10m 05s

Gerar números aleatórios em C# parece que deveria ser uma única linha, e em muitos casos é. Mas a linguagem oferece mais de uma maneira de produzir valores aleatórios, e as diferenças entre elas importam uma vez que você considera a segurança de thread, reprodutibilidade e uso. Escolher a abordagem errada pode introduzir bugs sutis no código multi-thread ou tornar um defeito relatado impossível de reproduzir.

Em seu vídeo "Gerando Números Aleatórios em C#", Tim Corey percorre a clássica classe Random, explica por que os valores de semente existem e introduz Random.Shared como o padrão moderno. Cobriremos cada abordagem junto com o raciocínio por trás dela, para que você possa escolher a certa sem adivinhação. Se você já se perguntou por que há múltiplos caminhos para algo que parece tão simples, este artigo explica.

Configurando a Demonstração

[0:11 - 0:59] Tim trabalha dentro de um aplicativo console rodando no Visual Studio 2026 (atualmente em preview) com .NET 10. Ele observa que tudo demonstrado aqui se aplica igualmente a .NET 9 e Visual Studio 2022, então você pode acompanhar com qualquer ferramenta que já tenha instalada.

O layout de demonstração é um loop for que imprime dois valores aleatórios lado a lado em cada iteração. Ter duas saídas rodando em paralelo facilita observar se ambos os geradores se comportam independentemente ou produzem resultados correspondentes, uma distinção que se torna importante assim que valores de seed entram na jogada.

A Classe Random Clássica

[0:59 - 3:28] A abordagem original para gerar inteiros aleatórios em C# envolve criar uma instância da classe Random:

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

Cada instância mantém seu próprio estado interno. Chamar .Next(1, 101) em qualquer um produz um inteiro entre 1 e 100. Tim destaca um detalhe que confunde os novatos: o valor mínimo é inclusivo, mas o máximo é exclusivo. Se você quer valores de 1 a 100, deve passar 1 e 101, não 1 e 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);

Executar a aplicação confirma que ambas as instâncias produzem sequências diferentes. Esse resultado parece intuitivo, mas o que acontece quando ambas as instâncias compartilham o mesmo ponto de partida conta uma história diferente.

Um aviso importante sobre essa abordagem: instâncias individuais de Random não são seguras para threads. Se sua aplicação realiza processamento paralelo e múltiplas threads acessam a mesma instância, o estado interno pode se corromper, produzindo zeros ou valores repetidos. A prática segura é criar uma instância por thread. Essa restrição é uma das razões pelas quais a linguagem mais tarde introduziu uma alternativa melhor.

Valores de Seed e Sequências Reproduzíveis

[3:28 - 6:00] Tim então passa uma seed explícita para ambos os construtores:

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

A saída muda drasticamente. Ambos os geradores agora produzem sequências idênticas: 79, 16, 25, 90, 50, 41, e assim por diante. Os números ainda são individualmente imprevisíveis se você não souber a seed, mas dado o mesmo valor inicial, a progressão é determinística.

Por que alguém iria querer isso? Tim dá um exemplo prático. Imagine um jogo que gera eventos aleatórios ao longo de uma sessão. Um jogador relata um bug, mas reproduzi-lo parece impossível porque os resultados foram randomizados. Se o jogo registra a semente usada para aquela sessão, um desenvolvedor pode recriar exatamente a mesma cadeia de decisões inicializando uma nova instância de Random com o mesmo valor. A mesma lógica se aplica a cenários de testes unitários onde você precisa de saídas consistentes para escrever asserções confiáveis contra comportamentos randomizados.

Instâncias com seed fornecem aleatoriedade controlada: uma sequência que parece imprevisível mas pode ser reproduzida sob demanda. Essa capacidade é a razão pela qual o construtor clássico Random que aceita uma semente não foi obsoleto, mesmo que uma API mais simples agora exista.

Random.Shared: O Padrão Moderno

[7:36 - 9:01] A partir do .NET 6, a abordagem recomendada para a maioria das gerações de números aleatórios é 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);

Não há instanciamento envolvido. Random.Shared é uma instância estática e segura para threads gerida pelo tempo de execução. Você chama .Next() (ou qualquer outro método na classe Random) e recebe um valor sem se preocupar com o tempo de vida do objeto ou com a concorrência.

Tim executa a demo duas vezes para provar o ponto. A primeira execução começa com 94 e 91; a segunda começa com 42 e 70. Ao contrário de uma instância com semente, Random.Shared parte de um estado inicial diferente a cada vez que o processo é iniciado. Você não pode definir uma seed, o que significa que você não pode produzir uma sequência reproduzível através desta API. Essa é a troca: simplicidade e segurança em troca de abrir mão da reprodução determinística.

Além de .Next(), Random.Shared expõe métodos para gerar doubles, preencher arrays de bytes e embaralhar coleções. Para a vasta maioria do código de aplicação onde você precisa de um valor aleatório rápido sem cerimônia, esta única propriedade estática substitui o boilerplate de gerenciar suas próprias instâncias.

Escolhendo a Abordagem Certa

[9:01 - 9:30] Tim fecha com uma estrutura de decisão concisa. Para aleatoriedade do dia a dia (escolher um valor, embaralhar uma lista, selecionar um elemento aleatório), Random.Shared é a escolha certa. Não requer configuração, lida com concorrência e se comporta corretamente entre threads.

Quando você precisa de uma sequência repetível de saídas, seja para depuração, testes ou simulação, crie uma instância dedicada de Random com uma semente conhecida. Lembre-se de que essas instâncias não são seguras para compartilhar entre threads.

E para qualquer coisa que envolva segurança (tokens, chaves, sais de senhas), nenhuma abordagem é apropriada. Tim direciona os espectadores para as bibliotecas criptográficas em System.Security.Cryptography, que produzem valores que não são apenas aleatórios, mas também resistentes à predição.

Encerrando: API Simples, Diferenças Significativas

[9:30 - 9:50] O que torna este tópico enganador é quão pouco código ele demanda. Uma única linha pode gerar um número aleatório através de qualquer uma dessas abordagens. A complexidade não está na sintaxe, mas em entender quais garantias cada método oferece: segurança de thread, reprodutibilidade ou força criptográfica.

Conclusão

[9:50 - 10:05] Para recapitular: Random.Shared cobre a maioria das necessidades com zero configuração e segurança de threads integrada. Instâncias de Random com semente permitem reproduzir uma sequência específica quando a depuração ou teste assim requer. Geradores criptográficos pertencem ao código sensível à segurança, onde a previsibilidade é uma vulnerabilidade, não uma característica.

Da próxima vez que procurar um número aleatório em C#, a decisão se resume a uma pergunta: você precisa reproduzir esta sequência mais tarde? Se a resposta for não, Random.Shared é tudo o que você precisa.

Dica de Exemplo: Ao chamar Random.Shared.Next(min, max), observe que max é exclusivo. Um intervalo de 1 a 100 requer passar 1 e 101. Esta margem de um é aplicável também às instâncias semeadas.

Assista ao vídeo completo no YouTube de Tim Corey e obtenha mais insights sobre fundamentos do C#.

Hero Worlddot related to Gerando Números Aleatórios em C#
Hero Affiliate related to Gerando Números Aleatórios em C#

Ganhe mais compartilhando o que você ama.

Você cria conteúdo para desenvolvedores que trabalham com .NET, C#, Java, Python ou Node.js? Transforme sua expertise em renda extra!

Equipe de suporte de ferro

Estamos online 24 horas por dia, 5 dias por semana.
Bater papo
E-mail
Liga para mim