<p>Mélangez n’importe quelle <code>(I)List</code> avec une méthode d’extension basée sur le <a href="https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle">mélange de Fisher-Yates</a> :</p>
<pre><code class="lang-auto">private static Random rng = new Random();
public static void Shuffle<T>(this IList<T> list)
{
int n = list.Count;
while (n > 1) {
n--;
int k = rng.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
</code></pre>
<p>Utilisation :</p>
<pre><code class="lang-auto">List<Product> products = GetProducts();
products.Shuffle();
</code></pre>
<p>Le code ci-dessus utilise la méthode <code>System.Random</code> souvent critiquée pour sélectionner les candidats à l’échange. C’est rapide mais pas aussi aléatoire que ça devrait l’être. Si vous avez besoin d’une meilleure qualité d’aléatoire dans vos mélanges, utilisez le générateur de nombres aléatoires dans <code>System.Security.Cryptography</code> comme ceci :</p>
<pre><code class="lang-auto">using System.Security.Cryptography;
...
public static void Shuffle<T>(this IList<T> list)
{
RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider();
int n = list.Count;
while (n > 1)
{
byte[] box = new byte[1];
do provider.GetBytes(box);
while (!(box[0] < n * (Byte.MaxValue / n)));
int k = (box[0] % n);
n--;
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
</code></pre>
<p>Une comparaison simple est disponible <a href="https://web.archive.org/web/20150801085341/http://blog.thijssen.ch/2010/02/when-random-is-too-consistent.html">sur ce blog</a> (WayBack Machine).</p>
<p>Edit : Depuis que j’ai écrit cette réponse il y a quelques années, beaucoup de personnes ont commenté ou m’ont écrit pour signaler la grosse erreur ridicule dans ma comparaison. Ils ont bien sûr raison. Il n’y a rien de mal avec <code>System.Random</code> s’il est utilisé comme prévu. Dans mon premier exemple ci-dessus, j’instancie la variable <code>rng</code> à l’intérieur de la méthode <code>Shuffle</code>, ce qui pose problème si la méthode est appelée de manière répétée. Ci-dessous se trouve un exemple complet corrigé basé sur un commentaire vraiment utile reçu aujourd’hui de <span class="mention">@weston</span> ici sur SO.</p>
<p>Program.cs :</p>
<pre><code class="lang-auto">using System;
using Sy
(Réponse tronquée)</code></pre>