Generate random enum in C# 2.0

Could someone please point me toward a cleaner method to generate a random enum member. This works but seems ugly.

Thanks!

public T RandomEnum<T>()
{
  string[] items = Enum.GetNames(typeof( T ));
  Random r = new Random();
  string e = items[r.Next(0, items.Length - 1)];
  return (T)Enum.Parse(typeof (T), e, true);
}

Answers


public T RandomEnum<T>()
{ 
  T[] values = (T[]) Enum.GetValues(typeof(T));
  return values[new Random().Next(0,values.Length)];
}

Thanks to @[Marc Gravell] for ponting out that the max in Random.Next(min,max) is exclusive.


Marxidad's answer is good (note you only need Next(0,values.Length), since the upper bound is exclusive) - but watch out for timing. If you do this in a tight loop, you will get lots of repeats. To make it more random, consider keeping the Random object in a field - i.e.

private Random rand = new Random();
public T RandomEnum<T>()
{ 
  T[] values = (T[]) Enum.GetValues(typeof(T));
  return values[rand.Next(0,values.Length)];
}

If it is a static field, you will need to synchronize access.


Silverlight does not have GetValues(), but you can use reflection to get a random enum instead.

private Random rnd = new Random();

public T RndEnum<T>()
{
    FieldInfo[] fields = typeof(T).GetFields(BindingFlags.Static | BindingFlags.Public);

    int index = rnd.Next(fields.Length);

    return (T) Enum.Parse(typeof(T), fields[index].Name, false);
}

I'm not sure about c# but other languages allow gaps in enum values. To account for that:

enum A {b=0,c=2,d=3,e=42};

switch(rand.Next(0,4))
{
   case 0: return A.b;
   case 1: return A.c;
   case 2: return A.d;
   case 3: return A.e;
}

The major down side is keeping it up to date!

Not near as neat but more correct in that corner case.


As pointed out, the examples from above index into an array of valid values and this get it right. OTOH some languages (cough D cough) don't provide that array so the above is useful enough that I'll leave it anyway.


Enum.Parse(typeof(SomeEnum), mRandom.Next(min, max).ToString()).ToString()

Need Your Help

How can I try a new language or framework without installing it?

web-applications sandbox

With so many languages and frameworks that exist, and with new ones appearing all the time, I don't have the time to download, install, and configure each one to evaluate it. In the past I've run a...

WM 5 SDK Symbol

c# sdk windows-mobile motorola-emdk

We have a large number of Window Mobile Devices (Symbol MC35 &amp; MC70). I want to write a small app that gets the device serial number and simcard serial number (not phone number). I have tryed u...