2009-11-17 18 views
6

मैं एक तरीका है जिसके एक .NET गणन में सबसे अधिक मूल्य निर्धारित करता है लिख रहा हूँ तो मैं प्रत्येक enum मूल्य के लिए एक बिट के साथ एक BitArray बना सकते हैं:एक गणन में सबसे अधिक मूल्य ढूँढना

pressedKeys = new BitArray(highestValueInEnum<Keys>()); 

मैं इस की जरूरत है []() int करने के लिए, EnumType के लिए नहीं []

/// <summary>Returns the highest value encountered in an enumeration</summary> 
/// <typeparam name="EnumType"> 
/// Enumeration of which the highest value will be returned 
/// </typeparam> 
/// <returns>The highest value in the enumeration</returns> 
private static int highestValueInEnum<EnumType>() { 
    int[] values = (int[])Enum.GetValues(typeof(EnumType)); 
    int highestValue = values[0]; 
    for(int index = 0; index < values.Length; ++index) { 
    if(values[index] > highestValue) { 
     highestValue = values[index]; 
    } 
    } 

    return highestValue; 
} 

आप देख सकते हैं, मैं Enum.GetValues ​​के रिटर्न मान कास्टिंग हूँ: दो अलग-अलग enumerations पर, तो मैं यह एक सामान्य विधि में बदल गया। ऐसा इसलिए है क्योंकि मैं बाद में intum करने के लिए EnumType (जो एक सामान्य प्रकार पैरामीटर है) नहीं डाला जा सकता है।

कोड काम करता है। लेकिन क्या यह मान्य है? क्या मैं हमेशा Enum.GetValues ​​() से int [] में वापसी कास्ट कर सकता हूं?

+0

संभावित enlicate [enum के अधिकतम मूल्य प्राप्त करना] (https://stackoverflow.com/questions/203377/getting-the-max-value-of-an-enum) – palswim

उत्तर

20

नहीं, आप सुरक्षित रूप से int[] पर नहीं जा सकते हैं। एनम प्रकार हमेशा अंतर्निहित मान के रूप में int का उपयोग नहीं करते हैं। यदि आप अपने आप को enum प्रकारों तक सीमित करते हैं जो करते हैं में अंतर्निहित प्रकार int है, तो यह ठीक होना चाहिए।

यह कुछ आप (या मैं) Unconstrained Melody विस्तार का समर्थन करने के सकता है अगर आप चाहते थे की तरह लगता है - एक तरह से जो सही मायने में प्रकार संकलन समय पर एक enum प्रकार होना करने के लिए विवश है, और किसी भी enum प्रकार के लिए काम किया, यहां तक ​​कि उन long और ulong जैसे अंतर्निहित आधारों के साथ।

बिना विघटित मेलोडी के, आप अभी भी इस तथ्य का उपयोग करके सामान्य तरीके से ऐसा कर सकते हैं कि सभी enum प्रकार प्रभावी ढंग से IComparable को लागू करते हैं। यदि आप .NET 3.5 का उपयोग कर रहे हैं तो यह एक-लाइनर है:

private static TEnum GetHighestValue<TEnum>() { 
    return Enum.GetValues(typeof(TEnum)).Cast<TEnum>().Max(); 
} 
+0

जॉन, माइक्रोसॉफ्ट संदर्भ क्यों "गणना तत्वों का डिफ़ॉल्ट अंतर्निहित प्रकार int है" अगर मैं किसी अन्य प्रकार को enum मान में असाइन नहीं कर सकता, न तो int32 के अलावा अन्य पूर्णांक प्रकार। मैंने बस 3 एल को एनम वैल्यू को असाइन करने की कोशिश की और संकलन त्रुटि मिली। –

+0

लूप में घुमावदार असाइनमेंट की रिपोर्ट करने के लिए धन्यवाद। मैंने पहले से ही इसे खोज लिया है और आपको एक पोस्ट किया गया है, जबकि आप अपनी पोस्ट लिख रहे होंगे ;-) – Cygon

+2

@ एंड्रे पेना: * डिफ़ॉल्ट * अंतर्निहित प्रकार एक enum है, लेकिन आप "enum foo" के रूप में एक enum घोषित कर सकते हैं : लंबा "इसके बजाए (आदि)। अधिक जानकारी के लिए सी # भाषा विनिर्देश देखें। –

0

आसान! LINQ का उपयोग करके आपके लूप को कोड की दो पंक्तियों के साथ प्रतिस्थापित किया जा सकता है, या केवल एक यदि आप इसे एक साथ जोड़ना चाहते हैं।

public partial class Form1 : Form 
{ 
    private void Form1_Load(object sender, EventArgs e) 
    { 
     MyEnum z = MyEnum.Second; 
     z++; 
     z++; 

     //see if a specific value is defined in the enum: 
     bool isInTheEnum = !Enum.IsDefined(typeof(MyEnum), z); 

     //get the max value from the enum: 
     List<int> allValues = new List<int>(Enum.GetValues(typeof(MyEnum)).Cast<int>()); 
     int maxValue = allValues.Max(); 
    } 


} 

public enum MyEnum 
{ 
    Zero = 0, 
    First = 1, 
    Second = 2, 
    Third = 3 
} 
+1

हालांकि 'सूची ' बनाने की परेशानी क्यों है? सभी मूल्यों को बफर करने की कोई आवश्यकता नहीं है ... –

+0

आप पूरी तरह से सही हैं, मैं इसे केवल var max = (int x से enum.GetValues ​​(typeof (MyEnum) में लिखा होगा।AsQueryable() एक्स का चयन करें) .मैक्स(); लेकिन यह कोड के बहुत दोस्ताना दिखने वाला टुकड़ा नहीं है, मैं इसे थोड़ा तोड़ना चाहता था और कोड को पढ़ने और जानकारीपूर्ण बनाने में आसान बना देता था। और मुझे नहीं लगता कि "मूल्यों को बफर करना" उच्चतम खोजने के लिए उन पर लूपिंग से कम इष्टतम है। – slugster

3

प्रति जॉन स्कीट की सलाह के रूप में (और तुम भी धन्यवाद, slugster), यह अब IComparable का उपयोग कर, क्योंकि मैं अभी भी .NET 2.0 लक्षित कर रहा हूँ अद्यतन कोड है।

/// <summary>Returns the highest value encountered in an enumeration</summary> 
/// <typeparam name="EnumType"> 
/// Enumeration of which the highest value will be returned 
/// </typeparam> 
/// <returns>The highest value in the enumeration</returns> 
private static EnumType highestValueInEnum<EnumType>() where EnumType : IComparable { 
    EnumType[] values = (EnumType[])Enum.GetValues(typeof(EnumType)); 
    EnumType highestValue = values[0]; 
    for(int index = 0; index < values.Length; ++index) { 
    if(values[index].CompareTo(highestValue) > 0) { 
     highestValue = values[index]; 
    } 
    } 

    return highestValue; 
} 

किसी को भी कोड पकड़ने के लिए, आप एक अतिरिक्त जांच जोड़ना चाहेंगे ताकि यह खाली enums पर उड़ न सके।

+0

निश्चित रूप से 'Array.Sort (मान);' आपके लूप से बेहतर होगा? – stevehipwell

+2

यह छोटा होगा, लेकिन ऐसा करने के बाद मैं एक सरणी को क्यों फेंकने जा रहा हूं? हो सकता है कि मैं यहां माइक्रो-ऑप्टिमाइज़िंग कर रहा हूं, लेकिन Array.Sort() बस मेरे लिए सहज नहीं लग रहा है। – Cygon

संबंधित मुद्दे