Question
I want to randomize the order of a generic List<T> in C#. I have a finite set of 75 numbers stored in a list, and I would like to place them into a random order so I can draw them one by one for a lottery-style application.
What is the best way to shuffle a List<T> so that each item has a fair chance of appearing in any position?
Short Answer
By the end of this page, you will understand how to shuffle a List<T> in C# using the correct approach, why some randomization techniques are biased or inefficient, and how to apply a proper shuffle in real applications such as games, lotteries, quizzes, and randomized processing.
Concept
Randomizing a list means reordering its elements so the order is unpredictable. In C#, this is commonly called shuffling a list.
The most important idea is that not all “random-looking” solutions are equally correct. A good shuffle should:
- Move every item exactly once into a new random position
- Give all possible orderings a fair chance
- Run efficiently, especially for larger lists
The standard algorithm for this is the Fisher-Yates shuffle. It works by walking backward through the list and swapping each element with a randomly chosen earlier element, including itself.
Why this matters:
- In a lottery-style app, you want each number to be equally likely to appear first, second, third, and so on.
- In games, biased shuffling can make results unfair.
- In testing or data processing, predictable or poor randomization can produce misleading outcomes.
A common beginner mistake is to sort by a random key, such as using OrderBy(x => random.Next()). This may look convenient, but it is not the best tool for a true shuffle and can be less efficient and potentially biased depending on collisions and implementation details.
So the core concept behind this question is not just “how do I randomize a list,” but how do I shuffle a list correctly and fairly in C#.
Mental Model
Imagine you have a deck of numbered cards.
You start at the last card position and say:
- "Pick any card from position
0to this position." - Swap it into the current spot.
- Move one position left and repeat.
This is like filling the list from the end backward, choosing a random remaining item each time.
Why this model is useful:
- At each step, you only choose from items not already locked into place.
- Once a position is filled, you never disturb it again.
- This guarantees a fair shuffle when done correctly.
So instead of “mixing everything around randomly,” think of shuffling as placing one random remaining item into each final position.
Syntax and Examples
The classic way to shuffle a List<T> in C# is to use the Fisher-Yates algorithm.
using System;
using System.Collections.Generic;
public static class ListExtensions
{
public static void Shuffle<T>(this List<T> list, Random rng)
{
for (int i = list.Count - 1; i > 0; i--)
{
int j = rng.Next(i + 1);
(list[i], list[j]) = (list[j], list[i]);
}
}
}
Example usage:
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
var numbers = new List<int>();
for (int i = 1; i <= 75; i++)
{
numbers.Add(i);
}
var rng = Random();
numbers.Shuffle(rng);
( number numbers)
{
Console.WriteLine(number);
}
}
}
Step by Step Execution
Consider this small list:
var numbers = new List<int> { 10, 20, 30, 40 };
var rng = new Random();
numbers.Shuffle(rng);
Using the shuffle method:
public static void Shuffle<T>(this List<T> list, Random rng)
{
for (int i = list.Count - 1; i > 0; i--)
{
int j = rng.Next(i + 1);
(list[i], list[j]) = (list[j], list[i]);
}
}
Let’s trace one possible run.
Initial list:
[10, 20, 30, 40]
Step 1
i = 3
- Randomly pick
jfrom0to3
Real World Use Cases
Shuffling a list is useful in many real applications:
- Lottery or bingo apps
- Randomize a fixed set of numbers and draw them one at a time.
- Card games
- Shuffle a deck before dealing cards.
- Quiz applications
- Randomize question order or answer choices.
- Music playlists
- Play songs in a random order.
- Load balancing or task processing
- Randomize work items to avoid fixed processing order.
- Testing and simulations
- Randomize data to test behavior under different input sequences.
Example: drawing lottery numbers one by one
var numbers = Enumerable.Range(1, 75).ToList();
numbers.Shuffle(new Random());
foreach (var draw in numbers)
{
Console.WriteLine($"Drawn: {draw}");
}
This approach is simple because the list is shuffled once, then consumed in order.
Real Codebase Usage
In real codebases, developers usually wrap shuffling logic in a reusable method or extension method so it can be applied anywhere.
Common patterns include:
Reusable extension method
This is the most common style for List<T>:
public static class ListExtensions
{
public static void Shuffle<T>(this List<T> list, Random rng)
{
for (int i = list.Count - 1; i > 0; i--)
{
int j = rng.Next(i + 1);
(list[i], list[j]) = (list[j], list[i]);
}
}
}
Validation and guard clauses
In production code, you often validate inputs early:
public static void Shuffle<T>(this List<T> list, Random rng)
{
if (list == null)
throw new ArgumentNullException((list));
(rng == )
ArgumentNullException((rng));
( i = list.Count - ; i > ; i--)
{
j = rng.Next(i + );
(list[i], list[j]) = (list[j], list[i]);
}
}
Common Mistakes
Here are the most common mistakes beginners make when randomizing a list in C#.
1. Creating Random repeatedly
Broken approach:
for (int i = 0; i < 10; i++)
{
var rng = new Random();
Console.WriteLine(rng.Next());
}
Problem:
- If
Randomis created many times in quick succession, it may use similar seeds. - That can produce repeated or low-quality results.
Better:
var rng = new Random();
for (int i = 0; i < 10; i++)
{
Console.WriteLine(rng.Next());
}
2. Using OrderBy(x => rng.Next()) as a shuffle
Example:
var shuffled = numbers.OrderBy(x => rng.Next()).ToList();
Why this is not ideal:
- It is less direct than Fisher-Yates.
- It depends on sorting instead of true in-place shuffling.
- Random key collisions can affect fairness.
Comparisons
Here is how common approaches compare.
| Approach | Fair shuffle | Performance | Changes original list | Notes |
|---|---|---|---|---|
| Fisher-Yates shuffle | Yes | Excellent, O(n) | Yes | Best standard choice for List<T> |
| Copy + Fisher-Yates | Yes | Good, O(n) plus copy | No | Best when original must stay unchanged |
OrderBy(x => rng.Next()) | Not ideal | Slower, O(n log n) | No | Convenient but not the preferred shuffle |
| Manual random picking with removal |
Cheat Sheet
public static void Shuffle<T>(this List<T> list, Random rng)
{
for (int i = list.Count - 1; i > 0; i--)
{
int j = rng.Next(i + 1);
(list[i], list[j]) = (list[j], list[i]);
}
}
Rules
- Use Fisher-Yates to shuffle a
List<T>fairly. - Loop from
list.Count - 1down to1. - Pick
jwithrng.Next(i + 1). - Swap
list[i]andlist[j]. - Reuse a single
Randominstance when possible.
Preserve the original list
var copy = new List<int>(original);
copy.Shuffle(rng);
Create a list of 1 through 75
FAQ
How do I shuffle a List<T> in C#?
Use the Fisher-Yates algorithm. It swaps each item with a randomly chosen earlier item, producing an efficient and fair shuffle.
Is OrderBy(x => random.Next()) a good way to randomize a list?
It may appear to work, but it is not the preferred method for a proper shuffle. Fisher-Yates is more efficient and more reliable for fair randomization.
Does shuffling a list change the original list?
Yes, if you shuffle in place. If you want to keep the original order, create a copy first and shuffle the copy.
Why should I reuse the same Random object?
Creating many Random instances quickly can lead to repeated or poor-quality random values. Reusing one instance avoids that problem.
Can I shuffle a list of any type, not just numbers?
Yes. A generic method like Shuffle<T> works with strings, objects, custom classes, and numbers.
What algorithm is typically used to shuffle a list?
The standard answer is the Fisher-Yates shuffle, sometimes called the Knuth shuffle.
How can I draw lottery numbers one at a time after shuffling?
Shuffle the list once, then read items from the beginning to the end. Each next item is the next draw.
Do I need LINQ to shuffle a list?
No. A loop with swaps is enough, and it is usually the better approach for this task.
Mini Project
Description
Build a simple lottery number drawer in C#. The program should create numbers from 1 to 75, shuffle them, and then display the numbers in the order they are drawn. This demonstrates how shuffling is used in a realistic application where each number should appear exactly once in a random order.
Goal
Create a console app that generates 75 numbers, shuffles them fairly, and prints them as lottery draws.
Requirements
- Create a list containing the numbers 1 through 75.
- Shuffle the list using a reusable
Shuffle<T>method. - Print each number in its randomized order.
- Ensure each number appears exactly once.
- Reuse a single
Randominstance.
Keep learning
Related questions
AddTransient vs AddScoped vs AddSingleton in ASP.NET Core Dependency Injection
Learn the differences between AddTransient, AddScoped, and AddSingleton in ASP.NET Core DI with examples and practical usage.
Best Way to Repeat a Character in C#: Building Repeated Strings Efficiently
Learn the best way to repeat a character in C#, compare StringBuilder, string concatenation, and simpler built-in options.
C# Array Initialization Syntaxes Explained
Learn all common C# array initialization syntaxes with examples, rules, comparisons, and mistakes beginners often make.