在C#2.0中生成随机枚举

有人可以指点我用一种更简洁的方法来生成随机枚举成员。 这有效,但看起来很难看。

谢谢!

public T RandomEnum() { 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); } 

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

感谢@ [Marc Gravell],他们认为Random.Next(min,max)中的max是独占的。

Marxidad的答案很好(注意你只需要Next(0,values.Length) ,因为上限是独占的) – 但要注意时间。 如果你在紧密的循环中这样做,你会得到很多重复。 为了使其更随机,请考虑将Random对象保留在字段中 – 即

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

如果是静态字段,则需要同步访问权限。

Silverlight没有GetValues(),但您可以使用reflection来获取随机枚举。

 private Random rnd = new Random(); public T RndEnum() { 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); } 

我不确定c#,但其他语言允许枚举值中的间隙。 为此解释:

 enum A {b=0,c=2,d=3,e=42}; switch(rand.Next(0,4)) { case 0: return Ab; case 1: return Ac; case 2: return Ad; case 3: return Ae; } 

主要的缺点是保持最新!

在那个角落的情况下,不是那么整洁但更正确。


正如所指出的,从上面的例子索引到一个有效值数组,这是正确的。 OTOH一些语言( 咳嗽 D )不提供那个数组,所以上面的内容非常有用,无论如何我都会留下它。

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