添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams Make sure you don't keep recreating random in a tight loop though - otherwise you'll keep getting the same value. ChrisF Jun 28, 2010 at 12:06 @uriDium No, the argument specifies which value is the first to be too big to be returned (i.e. max minus 1 ) mafu Sep 11, 2013 at 10:50 DarinDimitrov IMO the first comment by @ChrisF should be a note inside the answer with credit to Chris. Maytham Fahmi Oct 21, 2019 at 11:10 You do not need to subtract anything. Random.Next() returns a random integer that is less than the specified maximum. If you subtract, you will never get the last value in the enum. SnowGroomer Sep 2, 2021 at 19:58

Use Enum.GetValues to retrieve an array of all values. Then select a random array item.

static Random _R = new Random ();
static T RandomEnumValue<T> ()
    var v = Enum.GetValues (typeof (T));
    return (T) v.GetValue (_R.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
                With static T RandomEnumValue<T> () where T : Enum you can limit the generic types to only Enum. Otherwise you could pass any type... (More info)
– Flimtix
                Mar 2, 2022 at 9:29
    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());
  Three 
Three

You could also make it an extension: public static T GetRandomEnumValue<T>() where T : Enum => (T) Enum.GetValues(typeof(T)).OfType<Enum>().OrderBy(_ => Guid.NewGuid()).FirstOrDefault(); That simplifies its usage to: GetRandomEnumValue<EnumType>() – Travis Dec 20, 2020 at 23:42 I downvoted this question because it's not made clear why you would you generate N random GUIDs and then go through the trouble of sorting them, in light of a simple randomized index, which would've sufficed. – Zimano May 30, 2021 at 14:01 @kerzek This is an extension and has a specified type! He limited it with where T : Enum to only enums. – Flimtix Mar 2, 2022 at 9:47 If somebody is doing this in a loop they would call GetNames every time instead of caching it in an array. This would slow their code down so I don't see what's your contribution here? – Bojidar Stanchev Oct 10, 2019 at 10:56 @BojidarStanchev Your implied scenario of someone copy pasting this in a loop without adapting the code to their use case isn't a problem of the answer or the question, it's your own problem of misapplying the solution. – Zimano May 30, 2021 at 14:06 var values = Enum.GetValues(typeof(T)); return (T)values.GetValue(random.Next(values.Length));

Example of usage:

var random = new Random();
var myEnumRandom = random.NextEnum<MyEnum>();

The modern answer combining this answer and its comment:

public static class RandomExtensions
    private static Random Random = new Random();
    public static T GetRandom<T>() where T : struct, Enum
        T[]? v = Enum.GetValues<T>();
        return (T)v.GetValue(Random.Next(v.Length));
Keep the RNG creation outside the high frequency code.

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

Usage example:

System.Windows.Forms.Keys randomKey = RandomEnum<System.Windows.Forms.Keys>();
                @CodesInChaos You're right. Random.Next() is not threadsafe and will start returning zeroes when it breaks. I've updated my answer based on this info.
– WHol
                Aug 4, 2015 at 15:23

A lot of these answers are pretty old and - correct me if I'm wrong - seem to work with some sketchy concepts like type erasure and dynamic type casting. However, as user Yarek T points out, there's no need for that with the generic overload of Enum.GetValues:

static Random random = new Random();
// Somewhat unintuitively, we need to constrain the type parameter to
// both struct *and* Enum - struct is required b/c the type can't be
// nullable, and Enum is required b/c GetValues expects an Enum type.
// You'd think that Enum itself would satisfy the non-nullable
// constraint, but alas, me compiler tells me otherwise - perhaps
// someone more knowledgeable can explain why this is in a comment?
static TEnum RandomEnumValue<TEnum>() where TEnum : struct, Enum
    TEnum[] vals = Enum.GetValues<TEnum>();
    return vals[random.Next(vals.Length)];

Or, like in borja garcia's answer, we can even write this as an extension of the random class

public static class RandomExtensions
    public static TEnum NextEnumValue<TEnum>(this Random random)
        where TEnum : struct, Enum
        TEnum[] vals = Enum.GetValues<TEnum>();
        return vals[random.Next(vals.Length)];

And we can run the same test from mafu's answer:

Random random = new Random();
for (int i = 0; i < 10; i++) {
    var day = random.NextEnumValue<System.DayOfWeek>();
    Console.WriteLine(day.ToString());

Potential output:

Thursday
Saturday
Sunday
Sunday
Sunday
Saturday
Wednesday
Monday
Wednesday
Thursday

Personally, I'm a fan of extension methods, so I would use something like this (while not really an extension, it looks similar):

public enum Options {
    Zero,
    Three,
    Four,
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);
                As of C#7.3 you can constraint your generic type to be an enum: public static T Of<T>() where T : Enum learn.microsoft.com/en-us/visualstudio/releasenotes/…
– nitzel
                Aug 2, 2018 at 9:38
class Program {
  public static void Main (string[] args) {
    var max = Enum.GetValues(typeof(Test)).Length;
    var value = (Test)new Random().Next(0, max - 1);
    Console.WriteLine(value);

But you should use a better randomizer like the one in this library of mine.

Gah, almost. This fails for non-auto numbered enums. GetValues return you a list, Its safe to select a random element from that. – Yarek T Sep 20, 2021 at 11:19

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.