给定c#中的任意枚举,我如何选择一个随机值?
(我没有在SO上找到这个非常基本的问题。我将在一分钟内发布我的答案作为任何人的参考,但请随时发布你自己的答案。)
给定c#中的任意枚举,我如何选择一个随机值?
(我没有在SO上找到这个非常基本的问题。我将在一分钟内发布我的答案作为任何人的参考,但请随时发布你自己的答案。)
当前回答
改编为随机类扩展:
public static class RandomExtensions
{
public static T NextEnum<T>(this Random random)
{
var values = Enum.GetValues(typeof(T));
return (T)values.GetValue(random.Next(values.Length));
}
}
用法示例:
var random = new Random();
var myEnumRandom = random.NextEnum<MyEnum>();
其他回答
下面是一个使用LINQ的扩展方法的替代版本。
using System;
using System.Linq;
public static class EnumExtensions
{
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());
}
}
}
两个 一个 四个 四个 四个 三个 两个 四个 一个 三个
你可以这样做:
var rnd = new Random();
return (MyEnum) rnd.Next(Enum.GetNames(typeof(MyEnum)).Length);
不需要存储数组
你也可以强制转换一个随机值:
using System;
enum Test {
Value1,
Value2,
Value3
}
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);
}
}
但你应该用一个更好的随机器就像我这个库里的那个。
改编为随机类扩展:
public static class RandomExtensions
{
public static T NextEnum<T>(this Random random)
{
var values = Enum.GetValues(typeof(T));
return (T)values.GetValue(random.Next(values.Length));
}
}
用法示例:
var random = new Random();
var myEnumRandom = random.NextEnum<MyEnum>();
很多答案都很老了,而且——如果我说错了请纠正我——似乎只涉及一些粗略的概念,比如类型擦除和动态类型转换。然而,正如用户Yarek T指出的那样,Enum的通用重载不需要这样做。getvalue:
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)];
}
或者,像borja garcia的答案一样,我们甚至可以把它写成随机类的扩展
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)];
}
}
我们可以从mafu的答案中进行相同的测试:
Random random = new Random();
for (int i = 0; i < 10; i++) {
var day = random.NextEnumValue<System.DayOfWeek>();
Console.WriteLine(day.ToString());
}
潜在产出:
Thursday
Saturday
Sunday
Sunday
Sunday
Saturday
Wednesday
Monday
Wednesday
Thursday