2008-11-26 2 views
23

में यादृच्छिक enum उत्पन्न करें कोई मुझे यादृच्छिक enum सदस्य उत्पन्न करने के लिए एक क्लीनर विधि की ओर इंगित कर सकता है। यह काम करता है लेकिन बदसूरत लगता है।सी # 2.0

धन्यवाद! करने के लिए

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

उत्तर

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

धन्यवाद @ [मार्क Gravell] बाहर पोंटिंग कि Random.Next में अधिकतम (न्यूनतम, अधिकतम) अनन्य है।

+3

। – Dolphin

+1

ध्यान दें कि सिल्वरलाइट में Enum.GetValues ​​नहीं है। वैकल्पिक समाधान आगे नीचे देखें। –

+2

सावधान यह जवाब त्रुटिपूर्ण है। जैसा कि पहले कहा गया था कि पीढ़ी एक साथ तंग है, इसके परिणामस्वरूप कोई यादृच्छिकता नहीं होगी। – Luis

14

मार्क्सिडाड का जवाब अच्छा है (ध्यान दें कि आपको केवल 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)]; 
} 

, आप का उपयोग सिंक्रनाइज़ करने के लिए की आवश्यकता होगी।

+0

मेरे मामले में यह सिर्फ एक खेल के लिए कुछ डिफ़ॉल्ट उत्पन्न कर रहा है - बिल्कुल कोई लूप नहीं। सलाह के लिए धन्यवाद! – user10178

0

मुझे सी # के बारे में निश्चित नहीं है लेकिन अन्य भाषाएं एनम मूल्यों में अंतराल की अनुमति देती हैं। इसके लिए खाते:

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

प्रमुख नीचे की ओर इसे अद्यतित रख रहा है!

उस कोने के मामले में साफ लेकिन अधिक सही के करीब नहीं है।


जैसा कि बताया गया है, उपर्युक्त सूचकांक के उदाहरण मान्य मानों की सरणी में हैं और यह सही है। ओटीओएच कुछ भाषाओं (खांसी डी खांसी) उस सरणी को प्रदान न करें ताकि ऊपर इतना उपयोगी हो कि मैं इसे वैसे भी छोड़ दूंगा।

+0

मार्क्सिडाड इसके लिए एरे इंडेक्स लौटकर एनम के मूल्य को वापस कर देता है। मैंने वही किया जो मैंने सिर्फ सुंदर मार्ग लिया! – user10178

+0

यह स्पष्ट हो सकता है। Enum अपने मूल्य से सरणी में अपनी स्थिति से उत्पन्न होता है। – user10178

3

सिल्वरलाइट में GetValues ​​() नहीं है, लेकिन आप इसके बजाय यादृच्छिक enum प्राप्त करने के लिए प्रतिबिंब का उपयोग कर सकते हैं।

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); 
} 
+0

धन्यवाद, मुझे सिल्वरलाइट के लिए इसकी आवश्यकता थी! –

0
Enum.Parse(typeof(SomeEnum), mRandom.Next(min, max).ToString()).ToString() 
पाठ्यक्रम कोई वास्तविक कार्यान्वयन में आप (विशेष रूप से यदि आप इसे अक्सर कहते हैं) एक नया रैंडम हर कॉल का उपयोग नहीं करना चाहते और मैं व्यक्तिगत रूप से सरणी कैश करने के लिए चाहते हो जाएगा का
+0

यह विधि काम नहीं करती है अगर एनम वैल्यूज के संख्यात्मक मानों के बीच अंतराल हैं (और यह होने के लिए काफी संभव है)। – Styxxy