Effective Methods for Generating Random Unique Numbers in C#

Dec 09, 2025 · Programming · 10 views · 7.8

Keywords: C# | random numbers | unique values | list | shuffling algorithm

Abstract: This paper addresses the common issue of generating random unique numbers in C#, particularly the problem of duplicate values when using System.Random. It focuses on methods based on list checking and shuffling algorithms, providing detailed code examples and comparative analysis to help developers choose suitable solutions for their needs.

Problem Background

In C# programming, the System.Random class is commonly used for generating pseudo-random numbers. However, when multiple unique numbers need to be generated within a limited range, directly calling the Random.Next method often results in duplicate values. For instance, a typical scenario involves generating random integers between 0 and 9, where frequent calls may yield identical numbers due to the probabilistic nature of random number generators.

Method 1: Duplicate Checking Based on Lists

To avoid duplicates, one can maintain a list to store generated numbers and check for existence when generating new ones. This approach is straightforward and suitable for small-range number generation, but efficiency decreases as the list grows due to linear search overhead.

public Random rng = new Random();
public List<int> generatedNumbers = new List<int>();
private int currentRandomNumber;

private void GenerateUniqueRandomNumber()
{
    currentRandomNumber = rng.Next(0, 10);
    if (!generatedNumbers.Contains(currentRandomNumber))
    {
        generatedNumbers.Add(currentRandomNumber);
    }
}

In this code example, the Random instance is initialized at the class level to prevent re-declaration, while the list tracks generated values. Note that seed settings like DateTime.Now.Ticks.GetHashCode() are often unnecessary, as the default constructor of Random handles similar logic internally.

Method 2: Sequence Generation Based on Shuffling Algorithms

Another method involves generating all possible number sequences first, then randomizing their order through shuffling algorithms to ensure uniqueness. This approach generates all unique numbers at once, avoiding the overhead of duplicate checks, and is ideal for scenarios requiring complete random sequences.

using System;
using System.Collections.Generic;
using System.Linq;

public class Shuffler
{
    private Random rng = new Random();

    public void Shuffle<T>(IList<T> list)
    {
        for (int i = list.Count - 1; i > 0; i--)
        {
            int j = rng.Next(i + 1);
            T temp = list[i];
            list[i] = list[j];
            list[j] = temp;
        }
    }
}

// Usage example
var numbers = Enumerable.Range(0, 10).ToList();
Shuffler shuffler = new Shuffler();
shuffler.Shuffle(numbers);
// Now numbers contains a random unique sequence from 0 to 9, ready for traversal

This implementation is based on the Fisher-Yates shuffle algorithm, ensuring a uniform random distribution. Compared to simple swap methods, it avoids bias and is a standard practice for generating random unique sequences.

Discussion and Comparison

The list-based method is suitable for dynamically generating a small number of unique numbers, but checking overhead can become a bottleneck; the shuffling algorithm is better for pre-generating all numbers, guaranteeing uniqueness and performance. Other approaches, such as sorting with Guid.NewGuid(), are concise but inefficient and not recommended for random number generation. Developers should choose based on specific contexts: if the range is small and the number count is unknown, the list method is more flexible; if all numbers need to be generated at once, the shuffling algorithm is superior.

Conclusion

When generating random unique numbers in C#, understanding the limitations of System.Random and selecting appropriate algorithms is crucial. By combining list checking or shuffling techniques, duplicates can be effectively avoided, enhancing code reliability and efficiency. Future work may explore parallelization or cryptographic random number generators to expand application scenarios.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.