एक एनम का अधिकतम मूल्य प्राप्त करना


147

आपको एनम का अधिकतम मूल्य कैसे मिलता है?



1
मुझे लगता है कि कंपाइलर इसे रिफ्लेक्शन कॉल का उपयोग करने के बजाय संभाल सकता है। इस जानकारी के लिए संकलन-समय पद्धति का उपयोग करने वाले उत्तर को मेरा वोट प्राप्त होगा।
पाल्सविम

जवाबों:


214

Enum.GetValues ​​() क्रम में मानों को वापस करने के लिए लगता है, इसलिए आप ऐसा कुछ कर सकते हैं:

// given this enum:
public enum Foo
{
    Fizz = 3, 
    Bar = 1,
    Bang = 2
}

// this gets Fizz
var lastFoo = Enum.GetValues(typeof(Foo)).Cast<Foo>().Last();

संपादित करें

टिप्पणियों के माध्यम से पढ़ने के इच्छुक नहीं लोगों के लिए: आप इसे इस तरह भी कर सकते हैं:

var lastFoo = Enum.GetValues(typeof(Foo)).Cast<Foo>().Max();

... जो तब काम करेगा जब आपके कुछ एनम का मान नकारात्मक होगा।


3
अच्छा। का लाभ उठाते हुए: "सरणी के तत्वों को संलयन स्थिरांक के द्विआधारी मूल्यों द्वारा क्रमबद्ध किया जाता है।" से msdn.microsoft.com/en-us/library/system.enum.getvalues.aspx
TheSoftwareJedi

2
मैं अपना सिर हिला रहा था, यह सोचकर कि यह वास्तव में बहुत ही स्वादिष्ट है, लेकिन एक सुंदर समाधान दिया गया था। इसके अलावा अगर आप एनम वैल्यू का उपयोग करना चाहते हैं तो Convert.ToInt32 () का उपयोग करें। यह Google परिणामों के लिए है।
jdelator

53
यदि आप LINQ का उपयोग करने जा रहे हैं, तो अधिकतम () का उपयोग क्यों न करें, जो कि अधिक स्पष्ट है, और "लगता है" पर निर्भर नहीं है?
मार्क Gravell

3
यह बेहतर प्रदर्शन करता है, लेकिन केवल अगर एनम के मान नकारात्मक नहीं हैं, जो वे हो सकते हैं।
आईसीआर

4
मैं मैक्स () के लिए भी वोट करता हूं। अंतिम () विफल होगा यदि एनम नकारात्मक नहीं है, तो यहां
AZ।

41

मैं मैट के जवाब से सहमत हूं। यदि आपको केवल न्यूनतम और अधिकतम अंतर मानों की आवश्यकता है, तो आप इसे निम्नानुसार कर सकते हैं।

ज्यादा से ज्यादा:

Enum.GetValues(typeof(Foo)).Cast<int>().Max();

न्यूनतम:

Enum.GetValues(typeof(Foo)).Cast<int>().Min();

21

मैट हैमिल्टन के उत्तर के अनुसार, मैंने इसके लिए एक एक्सटेंशन विधि बनाने पर विचार किया।

चूंकि ValueTypeमुझे सामान्य प्रकार के पैरामीटर की कमी के रूप में स्वीकार नहीं किया गया है, इसलिए मुझे इसे प्रतिबंधित Tकरने के लिए एक बेहतर तरीका नहीं मिला Enum

किसी भी विचार वास्तव में सराहना की जाएगी।

पुनश्च। कृपया मेरे VB गर्भनिरोधक को नजरअंदाज करें, मुझे VB का इस तरह से उपयोग करना पसंद है, यही VB की ताकत है और इसलिए मैं VB से प्यार करता हूं।

होवेवा, यहाँ यह है:

सी#:

static void Main(string[] args)
{
    MyEnum x = GetMaxValue<MyEnum>(); //In newer versions of C# (7.3+)
    MyEnum y = GetMaxValueOld<MyEnum>();  
}

public static TEnum GetMaxValue<TEnum>()
  where TEnum : Enum
{
     return Enum.GetValues(typeof(TEnum)).Cast<TEnum>().Max();
}

//When C# version is smaller than 7.3, use this:
public static TEnum GetMaxValueOld<TEnum>()
  where TEnum : IComparable, IConvertible, IFormattable
{
    Type type = typeof(TEnum);

    if (!type.IsSubclassOf(typeof(Enum)))
        throw new
            InvalidCastException
                ("Cannot cast '" + type.FullName + "' to System.Enum.");

    return (TEnum)Enum.ToObject(type, Enum.GetValues(type).Cast<int>().Last());
}



enum MyEnum
{
    ValueOne,
    ValueTwo
}

वीबी:

Public Function GetMaxValue _
    (Of TEnum As {IComparable, IConvertible, IFormattable})() As TEnum

    Dim type = GetType(TEnum)

    If Not type.IsSubclassOf(GetType([Enum])) Then _
        Throw New InvalidCastException _
            ("Cannot cast '" & type.FullName & "' to System.Enum.")

    Return [Enum].ToObject(type, [Enum].GetValues(type) _
                        .Cast(Of Integer).Last)
End Function

इसके लिए stackoverflow.com/questions/79126/… देखें : if ((type.IsEnum)
कंक्रीट गनेट

आप अपने "स्ट्रक्चर" को भी जोड़ सकते हैं जहां यह सुनिश्चित करेगा कि यह एक वैल्यू टाइप है, लेकिन इसे Enum तक सीमित न रखें यह वह है जो मैं उपयोग करता हूं: जहां T: संरचना, IComparable, IFormattable
jdawiz

2
आप अपना उत्तर अपडेट कर सकते हैं। C # 7.3 में आप वास्तव में विस्तार विधि कर सकते हैं और Enum प्रकार (संरचना के बजाय) तक सीमित कर सकते हैं।
नॉर्ड्स

हालांकि यह एक विस्तार विधि नहीं है। लेकिन एक अच्छी उपयोगिता विधि।
रे

14

यह थोड़ा नाइटपिक है लेकिन किसी enumका वास्तविक अधिकतम मूल्य है Int32.MaxValue(यह माना जाता है कि यह एक enumव्युत्पन्न है int)। किसी भी Int32मूल्य को किसी भी मूल्य पर रखना पूरी तरह से कानूनी है enumचाहे वह वास्तव में उस मूल्य के साथ एक सदस्य घोषित किया हो या नहीं।

कानूनी:

enum SomeEnum
{
    Fizz = 42
}

public static void SomeFunc()
{
    SomeEnum e = (SomeEnum)5;
}

मेरे पास ऐसे मामले हैं जहां लौटे हुए ईमू के लिए एक इंटेगर चर सेट करना एक बेमिसाल मूल्य की आपूर्ति होने पर टाइप बेमेल के साथ विफल हो जाता है, इसलिए इसके बजाय लॉन्ग का उपयोग करना सबसे अच्छा है (यदि आप आलस्य से त्रुटि ठीक से नहीं फंसे हैं!)।
AjV Jsy

9

दूसरी बार आजमाने के बाद, मुझे यह एक्सटेंशन विधि मिली:

public static class EnumExtension
{
    public static int Max(this Enum enumType)
    {           
        return Enum.GetValues(enumType.GetType()).Cast<int>().Max();             
    }
}

class Program
{
    enum enum1 { one, two, second, third };
    enum enum2 { s1 = 10, s2 = 8, s3, s4 };
    enum enum3 { f1 = -1, f2 = 3, f3 = -3, f4 };

    static void Main(string[] args)
    {
        Console.WriteLine(enum1.one.Max());        
    }
}

5

अंतिम फ़ंक्शन का उपयोग करें अधिकतम मान प्राप्त नहीं कर सका। "अधिकतम" फ़ंक्शन का उपयोग कर सकते हैं। पसंद:

 class Program
    {
        enum enum1 { one, two, second, third };
        enum enum2 { s1 = 10, s2 = 8, s3, s4 };
        enum enum3 { f1 = -1, f2 = 3, f3 = -3, f4 };

        static void Main(string[] args)
        {
            TestMaxEnumValue(typeof(enum1));
            TestMaxEnumValue(typeof(enum2));
            TestMaxEnumValue(typeof(enum3));
        }

        static void TestMaxEnumValue(Type enumType)
        {
            Enum.GetValues(enumType).Cast<Int32>().ToList().ForEach(item =>
                Console.WriteLine(item.ToString()));

            int maxValue = Enum.GetValues(enumType).Cast<int>().Max();     
            Console.WriteLine("The max value of {0} is {1}", enumType.Name, maxValue);
        }
    }

4

C # के लिए मैथ्यू जे सुलिवन के साथ समझौता:

   Enum.GetValues(typeof(MyEnum)).GetUpperBound(0);

मुझे वास्तव में यकीन नहीं है कि कोई क्यों उपयोग करना चाहेगा:

   Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().Last();

... शब्द के लिए शब्द के रूप में, शब्दार्थ, यह उतना समझ में नहीं आता है? (हमेशा अलग-अलग तरीकों से अच्छा होता है, लेकिन मुझे बाद में इसका फायदा नहीं दिखता है।)


4
GetUpperBound का उपयोग करना मेरे लिए एक गिनती (4, 40 नहीं) लौटाता है: MyEnum {a = 0, b = 10, c = 20, d = 30, e = 40}
alirobe

अच्छी पकड़ है, मैंने उस पर ध्यान नहीं दिया था। ठीक है, इसलिए यह संस्करण मानक ऑटो-एनम के लिए बहुत अच्छा है, लेकिन कस्टम मूल्यों के साथ एनमों के लिए नहीं। मुझे लगता है कि विजेता श्री हैमिल्टन बने हुए हैं। :)
इंजीनियर

जब आपका Enum में बिटकॉइन वैल्यू हो तो GetUpperBound अच्छा है। (अर्थात - 1, 2, 4, 8, आदि)। उदाहरण के लिए, यदि आप एक इकाई परीक्षण लिख रहे थे, तो आप लूप डब्ल्यू / इस कई पुनरावृत्तियों के माध्यम से काम करना चाहेंगे: Math.Pow (2, Enum.GetValues ​​(टाइपो (MyEnum)))। GetUpperBound (0))।
WEFX

लंबाई में गलत क्या है (एनम में मानों की संख्या के लिए)? सरल बेहतर है। (ऐसा नहीं है कि यह मूल प्रश्न का उत्तर देता है।)
इयान गोल्डबी

2

System.Enum के तहत प्रगणित प्रकारों के बारे में जानकारी प्राप्त करने की विधियाँ हैं।

तो, Visual Studio I में VB.Net प्रोजेक्ट में "System.Enum" टाइप कर सकते हैं। और अंतर्मुखता सभी प्रकार की अच्छाई लाती है।

विशेष रूप से एक विधि System.Enum.GetValues ​​() है, जो एन्यूमरेटेड मानों की एक सरणी देता है। एक बार जब आपको सरणी मिल जाती है, तो आपको अपने विशेष परिस्थितियों के लिए जो भी उपयुक्त हो, करने में सक्षम होना चाहिए।

मेरे मामले में, मेरे गणना किए गए मान शून्य पर शुरू हुए और कोई संख्या नहीं छोड़ी, इसलिए मेरी गणना के लिए अधिकतम मूल्य प्राप्त करने के लिए मुझे बस यह जानना होगा कि सरणी में कितने तत्व थे।

VB.Net कोड स्निपेट:

'''''''

Enum MattType
  zerothValue         = 0
  firstValue          = 1
  secondValue         = 2
  thirdValue          = 3
End Enum

'''''''

Dim iMax      As Integer

iMax = System.Enum.GetValues(GetType(MattType)).GetUpperBound(0)

MessageBox.Show(iMax.ToString, "Max MattType Enum Value")

'''''''

सरणी के अंतराल होने पर काम नहीं करता है। यह केवल दुर्घटना से भी काम करता है, क्योंकि तत्व सूचकांक उस सूचकांक में संग्रहीत मूल्य के बराबर होता है। द्वारा दिए गए सरणी में GetUpperBound()उच्चतम संभव सूचकांक को पुनः प्राप्त करता है GetValues(), उस सरणी के अंदर संग्रहीत उच्चतम मूल्य नहीं।
22

2

F # में, enum को एक अनुक्रम में बदलने के लिए एक सहायक फ़ंक्शन के साथ:

type Foo =
    | Fizz  = 3
    | Bang  = 2

// Helper function to convert enum to a sequence. This is also useful for iterating.
// stackoverflow.com/questions/972307/can-you-loop-through-all-enum-values-c
let ToSeq (a : 'A when 'A : enum<'B>) =
    Enum.GetValues(typeof<'A>).Cast<'B>()

// Get the max of Foo
let FooMax = ToSeq (Foo()) |> Seq.max   

इसे चला रहे हैं ...

> प्रकार फू = | फ़िज़ = 3 | बंग = २
> वैल टुसेक: 'ए -> सीक <' बी> जब 'ए: एनम <' बी>
> वैल फ़ूमैक्स: फू = फ़िज़

when 'A : enum<'B>परिभाषा के लिए संकलक द्वारा की आवश्यकता नहीं है, लेकिन ToSeq के किसी भी उपयोग के लिए आवश्यक है, यहां तक कि एक वैध enum प्रकार के आधार पर।


1

यह सभी परिस्थितियों में उपयोग करने योग्य नहीं है, लेकिन मैं अक्सर अधिकतम मूल्य को स्वयं परिभाषित करता हूं:

enum Values {
  one,
  two,
  tree,
  End,
}

for (Values i = 0; i < Values.End; i++) {
  Console.WriteLine(i);
}

var random = new Random();
Console.WriteLine(random.Next((int)Values.End));

जब आप किसी एनम में कस्टम मान का उपयोग करते हैं तो निश्चित रूप से यह काम नहीं करेगा, लेकिन अक्सर यह एक आसान समाधान हो सकता है।


1

जब मैंने अपने एनम के न्यूनतम और अधिकतम मानों की आवश्यकता की तो मैंने निम्नलिखित का उपयोग किया। मैं बस गणना के न्यूनतम मूल्य के बराबर एक मिनट सेट करता हूं और एन्यूमरेशन में उच्चतम मान के बराबर अधिकतम होता है।

public enum ChannelMessageTypes : byte
{
    Min                 = 0x80, // Or could be: Min = NoteOff
    NoteOff             = 0x80,
    NoteOn              = 0x90,
    PolyKeyPressure     = 0xA0,
    ControlChange       = 0xB0,
    ProgramChange       = 0xC0,
    ChannelAfterTouch   = 0xD0,
    PitchBend           = 0xE0,
    Max                 = 0xE0  // Or could be: Max = PitchBend
}

// I use it like this to check if a ... is a channel message.
if(... >= ChannelMessageTypes.Min || ... <= ChannelMessages.Max)
{
    Console.WriteLine("Channel message received!");
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.