24

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

谢谢!

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

5 回答 5

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

感谢@[Marc Gravell] 指出 Random.Next(min,max) 中的最大值是独占的。

于 2008-11-26T05:22:42.147 回答
15

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

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

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

于 2008-11-26T05:32:59.227 回答
3

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

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);
}
于 2009-12-15T21:16:41.590 回答
0

我不确定 c# 但其他语言允许枚举值中的空白。为了解决这个问题:

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

主要的缺点是保持最新!

在那个角落里,没有那么整洁,但更正确。


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

于 2008-11-26T06:00:52.180 回答
0
Enum.Parse(typeof(SomeEnum), mRandom.Next(min, max).ToString()).ToString()
于 2012-01-05T03:06:51.360 回答