2010-06-28 6 views

Répondre

209
Array values = Enum.GetValues(typeof(Bar)); 
Random random = new Random(); 
Bar randomBar = (Bar)values.GetValue(random.Next(values.Length)); 
+28

Assurez-vous que vous ne gardez pas recréer 'random' dans une boucle serrée bien - sinon vous allez continuer à obtenir la même valeur. – ChrisF

+0

Devrait-elle être aléatoire.Next (values.Length -1)? – uriDium

+3

@uriDium Non, l'argument spécifie quelle valeur est la première à être trop grande pour être renvoyée (c.-à-d._max minus 1_) – mafu

47

Utilisez Enum.GetValues ​​à 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 utilisée à l'origine OrderBy (x => _Random.Next()).FirstOrDefault() pour sélectionner un élément aléatoire. Ne l'utilisez que si vous êtes irrationnellement attiré 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.

2

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

2

Voici une fonction générique pour cela. Conserver la création 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>(); 
+0

Avoir une méthode statique qui n'est pas threadsafe est assez dangereux. – CodesInChaos

+0

@CodesInChaos Vous avez raison. Random.Next() n'est pas threadsafe et commencera à renvoyer des zéros lorsqu'il se casse. J'ai mis à jour ma réponse basée sur cette information. – WHol

0

Personnellement, je suis fan des méthodes d'extension, donc j'utiliser quelque chose comme ça (alors pas vraiment une extension, il ressemble):

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); 
     } 
    } 

} 
0

Voici une autre version 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

Vous pouvez simplement faire ceci:

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

Pas besoin de stocker des tableaux

+0

'GetNames' renvoie un tableau. –

+0

Je voulais dire que vous n'avez pas besoin de le stocker. Ma faute –

Questions connexes