在C#2.0中生成随机枚举

在C#2.0中生成随机枚举,c#,enums,C#,Enums,有人能告诉我一个更干净的方法来生成一个随机枚举成员吗。这很管用,但看起来很难看 谢谢 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); } pub

有人能告诉我一个更干净的方法来生成一个随机枚举成员吗。这很管用,但看起来很难看

谢谢

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);
}
publictrandomenum()
{
string[]items=Enum.GetNames(typeof(T));
随机r=新随机();
字符串e=项[r.Next(0,items.Length-1)];
返回(T)Enum.Parse(typeof(T),e,true);
}
public T RandomEnum()
{ 
T[]values=(T[])Enum.GetValues(typeof(T));
返回值[new Random().Next(0,values.Length)];
}
多亏了@[Marc Gravell]指出了Random.Next中的max(min,max)是排他性的。

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

private Random rand = new Random();
public T RandomEnum<T>()
{ 
  T[] values = (T[]) Enum.GetValues(typeof(T));
  return values[rand.Next(0,values.Length)];
}
private Random rand=new Random();
公共T随机数()
{ 
T[]values=(T[])Enum.GetValues(typeof(T));
返回值[rand.Next(0,values.Length)];
}
如果是静态字段,则需要同步访问。

我不确定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;
}
主要的缺点是保持最新

不太整洁,但在那个角落里更正确



如前所述,上面的示例将索引到一个有效值数组中,这就正确了。有些语言(cough D cough)不提供该数组,因此上面的内容非常有用,我还是不使用它。

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);
}
private Random rnd=new Random();
公共财政
{
FieldInfo[]fields=typeof(T).GetFields(BindingFlags.Static | BindingFlags.Public);
int index=rnd.Next(fields.Length);
返回(T)Enum.Parse(typeof(T),字段[index].Name,false);
}

在我的例子中,它只是为游戏生成一些默认值——根本没有循环。谢谢你的建议!marxidad通过返回数组索引而不是枚举值来解释这一点。我也这么做了,我只是走了一条风景优美的路线!这可能会更清楚。枚举是由其在数组中的位置而不是其值生成的。当然,在实际实现中,您不希望每次调用都使用新的随机值(特别是如果您经常调用它),我个人希望缓存数组。请注意Silverlight没有enum.GetValues。请进一步查看备选解决方案。请注意,此答案有缺陷。正如前面所说的,如果这一代人紧密地团结在一起,这将不会导致任何随机性。谢谢,我需要这个Silverlight!如果枚举值的数值之间存在间隙(这很可能发生),则此方法不起作用。
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);
}
Enum.Parse(typeof(SomeEnum), mRandom.Next(min, max).ToString()).ToString()