2010-06-28 41 views

Trả lời

209
Array values = Enum.GetValues(typeof(Bar)); 
Random random = new Random(); 
Bar randomBar = (Bar)values.GetValue(random.Next(values.Length)); 
+28

Hãy chắc chắn rằng bạn không giữ tái tạo 'random' trong một vòng lặp chặt chẽ mặc dù - nếu không bạn sẽ tiếp tục nhận được giá trị như nhau. – ChrisF

+0

Điều đó có nên ngẫu nhiên không. Tiếp theo (giá trị.Length -1)? – uriDium

+3

@uriDium Không, đối số chỉ định giá trị nào là giá trị đầu tiên quá lớn để trả lại (tức là_max trừ 1_) – mafu

47

Sử dụng Enum.GetValues ​​để truy xuất một mảng của tất cả các giá trị. Sau đó chọn một mục mảng ngẫu nhiên.

static T RandomEnumValue<T>() 
{ 
    var v = Enum.GetValues (typeof (T)); 
    return (T) v.GetValue (new Random().Next(v.Length)); 
} 

Test:

for (int i = 0; i < 10; i++) { 
    var value = RandomEnumValue<System.DayOfWeek>(); 
    Console.WriteLine (value.ToString()); 
} 

->

Tuesday 
Saturday 
Wednesday 
Monday 
Friday 
Saturday 
Saturday 
Saturday 
Friday 
Wednesday 

Cập nhật: Câu trả lời này ban đầu được sử dụng OrderBy (x => _Random.Next()).FirstOrDefault() để chọn một yếu tố ngẫu nhiên. Chỉ sử dụng nó nếu bạn bị thu hút một cách phi lý bởi các phím ngẫu nhiên. Trong bất kỳ trường hợp nào khác, thay vào đó, hãy sử dụng câu trả lời được chấp nhận bởi Darin Dimitrov, mà tôi đã đưa vào câu trả lời này sau.

2

Gọi Enum.GetValues; điều này trả về một mảng đại diện cho tất cả các giá trị có thể cho enum của bạn. Chọn một mục ngẫu nhiên từ mảng này. Đúc mục đó trở lại kiểu enum gốc.

2

Đây là chức năng chung cho nó. Giữ việc tạo RNG bên ngoài mã tần số cao.

public static Random RNG = new Random(); 

public static T RandomEnum<T>() 
{ 
    Type type = typeof(T); 
    Array values = Enum.GetValues(type); 
    lock(RNG) 
    { 
     object value= values.GetValue(RNG.Next(values.Length)); 
     return (T)Convert.ChangeType(value, type); 
    } 
} 

Cách sử dụng Ví dụ:

System.Windows.Forms.Keys randomKey = RandomEnum<System.Windows.Forms.Keys>(); 
+0

Có một phương pháp tĩnh không phải là luồng an toàn là khá nguy hiểm. – CodesInChaos

+0

@CodesInChaos Bạn nói đúng. Random.Next() không phải là luồng an toàn và sẽ bắt đầu trả về số 0 khi nó bị hỏng. Tôi đã cập nhật câu trả lời của mình dựa trên thông tin này. – WHol

0

Cá nhân, tôi là một fan hâm mộ của phương pháp khuyến nông, vì vậy tôi sẽ sử dụng một cái gì đó như thế này (mặc dù không thực sự là một phần mở rộng, có vẻ tương tự):

public enum Options { 
    Zero, 
    One, 
    Two, 
    Three, 
    Four, 
    Five 
} 

public static class RandomEnum { 
    private static Random _Random = new Random(Environment.TickCount); 

    public static T Of<T>() { 
     if (!typeof(T).IsEnum) 
      throw new InvalidOperationException("Must use Enum type"); 

     Array enumValues = Enum.GetValues(typeof(T)); 
     return (T)enumValues.GetValue(_Random.Next(enumValues.Length)); 
    } 
} 

[TestClass] 
public class RandomTests { 
    [TestMethod] 
    public void TestMethod1() { 
     Options option; 
     for (int i = 0; i < 10; ++i) { 
      option = RandomEnum.Of<Options>(); 
      Console.WriteLine(option); 
     } 
    } 

} 
0

Đây là phiên bản thay thế là Extension Method sử dụng 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()); 
     } 
    }   
} 

Hai
Một
Bốn
Bốn
Bốn
Ba
Hai
Bốn
Một
Ba

1

Bạn chỉ có thể làm điều này:

var rnd = new Random(); 
return (MyEnum) rnd.Next(Enum.GetNames(typeof(MyEnum)).Length); 

Không cần phải lưu trữ mảng

+0

'GetNames' trả về một mảng. –

+0

Tôi có nghĩa là bạn không cần phải lưu trữ nó. Lỗi của tôi –

Các vấn đề liên quan