Comment sélectionner une valeur aléatoire à partir d'une énumération?

Étant donné une énumération arbitraire en C#, Comment puis-je sélectionner une valeur aléatoire?

(Je n'ai pas trouvé cette question très basique sur SO. Je posterai ma réponse dans une minute comme référence pour n'importe qui, mais n'hésitez pas à poster votre propre réponse.)

134
demandé sur mafu 2010-06-28 15:59:28

7 réponses

Array values = Enum.GetValues(typeof(Bar));
Random random = new Random();
Bar randomBar = (Bar)values.GetValue(random.Next(values.Length));
233
répondu Darin Dimitrov 2010-06-28 12:03:26

Utilisez Enum.GetValues pour récupérer un tableau de toutes les valeurs. Ensuite, sélectionnez un élément de tableau aléatoire.

static T RandomEnumValue<T> ()
{
    var v = Enum.GetValues (typeof (T));
    return (T) v.GetValue (new Random ().Next(v.Length));
}

Test:

for (int i = 0; i < 10; i++) {
    var value = RandomEnumValue<System.DayOfWeek> ();
    Console.WriteLine (value.ToString ());
}

->

Tuesday
Saturday
Wednesday
Monday
Friday
Saturday
Saturday
Saturday
Friday
Wednesday

Mise à jour: cette réponse utilisait à l'origine OrderBy (x => _Random.Next()).FirstOrDefault () pour sélectionner un élément aléatoire. Utilisez-le uniquement si vous êtes irrationnellement attiré par le brassage par des touches aléatoires. Dans tous les autres cas, utilisez plutôt la réponse acceptée par Darin Dimitrov, que j'ai incorporée dans cette réponse plus tard.

52
répondu mafu 2015-08-04 22:07:34

Appelez Enum.GetValues; cela renvoie un tableau qui représente toutes les valeurs possibles pour votre énumération. Choisissez un élément aléatoire dans ce tableau. Renvoyez cet élément au type enum d'origine.

2
répondu Tim Robinson 2010-06-28 12:02:30

Voici une fonction générique pour elle. Gardez la création de RNG en dehors du code haute fréquence.

public static Random RNG = new Random();

public static T RandomEnum<T>()
{  
    Type type = typeof(T);
    Array values = Enum.GetValues(type);
    lock(RNG)
    {
        object value= values.GetValue(RNG.Next(values.Length));
        return (T)Convert.ChangeType(value, type);
    }
}

Exemple d'Utilisation:

System.Windows.Forms.Keys randomKey = RandomEnum<System.Windows.Forms.Keys>();
2
répondu WHol 2015-08-04 17:54:42

Vous pouvez simplement faire ceci:

var rnd = new Random();
return (MyEnum) rnd.Next(Enum.GetNames(typeof(MyEnum)).Length);

Pas besoin de stocker des tableaux

2
répondu Breno Angelotti 2017-06-13 16:35:39

Personnellement, je suis un fan des méthodes d'extension, donc j'utiliserais quelque chose comme ceci (bien que ce ne soit pas vraiment une extension, cela semble similaire):

public enum Options {
    Zero,
    One,
    Two,
    Three,
    Four,
    Five
}

public static class RandomEnum {
    private static Random _Random = new Random(Environment.TickCount);

    public static T Of<T>() {
        if (!typeof(T).IsEnum)
            throw new InvalidOperationException("Must use Enum type");

        Array enumValues = Enum.GetValues(typeof(T));
        return (T)enumValues.GetValue(_Random.Next(enumValues.Length));
    }
}

[TestClass]
public class RandomTests {
    [TestMethod]
    public void TestMethod1() {
        Options option;
        for (int i = 0; i < 10; ++i) {
            option = RandomEnum.Of<Options>();
            Console.WriteLine(option);
        }
    }

}
1
répondu Dan Champagne 2015-08-04 16:11:06

Voici une version alternative en tant que Extension Method en utilisant LINQ.

using System;
using System.Linq;

public static class EnumExtensions
{
    public static Enum GetRandomEnumValue(this Type t)
    {
        return Enum.GetValues(t)          // get values from Type provided
            .OfType<Enum>()               // casts to Enum
            .OrderBy(e => Guid.NewGuid()) // mess with order of results
            .FirstOrDefault();            // take first item in result
    }
}

public static class Program
{
    public enum SomeEnum
    {
        One = 1,
        Two = 2,
        Three = 3,
        Four = 4
    }

    public static void Main()
    {
        for(int i=0; i < 10; i++)
        {
            Console.WriteLine(typeof(SomeEnum).GetRandomEnumValue());
        }
    }           
}

Deux
Un
Quatre
Quatre
Quatre
Trois
Deux
Quatre
Un
Trois

1
répondu Aaron Hudon 2017-09-23 15:25:44