सवाल मैं एक enum कैसे गणना करते हैं?


आप कैसे गणना कर सकते हैं enum सी # में?

जैसे निम्न कोड संकलित नहीं करता है:

public enum Suit 
{
    Spades,
    Hearts,
    Clubs,
    Diamonds
}

public void EnumerateAllSuitsDemoMethod() 
{
    foreach (Suit suit in Suit) 
    {
        DoSomething(suit);
    }
}

और निम्नलिखित संकलन-समय त्रुटि देता है:

'सूट' एक 'प्रकार' है लेकिन इसका प्रयोग 'चर'

यह पर विफल रहता है Suit कीवर्ड, दूसरा।


3119
2017-09-19 20:34


मूल


यह भी देखें ... stackoverflow.com/questions/972307/... - SteveC
@ChaseMedallion आपका लिंक मर गया प्रतीत होता है। - Clearer
आप जांचना चाह सकते हैं सी # enums के इन्स और बहिष्कार, जो इस के साथ-साथ अन्य उपयोगी enum tidbits पर चर्चा करता है - ChaseMedallion
@ क्लेयर धन्यवाद मैंने लिंक अपडेट किया है। - ChaseMedallion


जवाब:


foreach (Suit suit in (Suit[]) Enum.GetValues(typeof(Suit)))
{
}

3896
2017-09-19 20:37



यदि आपके पास गणनाकर्ता सूची में डुप्लिकेट मान हैं तो यह काम नहीं करता है। - Jessy
मैं बस यह इंगित करना चाहता हूं कि दुर्भाग्य से चांदी की रोशनी में काम नहीं करेगा, क्योंकि चांदी की रोशनी में शामिल नहीं है enum.GetValues। आपको इस मामले में प्रतिबिंब का उपयोग करना होगा। - Giacomo Tagliabue
@ जेसी यह कर देता है डुप्लिकेट स्थितियों के मामले में काम करते हैं enum E {A = 0, B = 0}। Enum.GetValues परिणाम दो मूल्यों में लौटाए जा रहे हैं, हालांकि वे वही हैं। E.A == E.B सच है, इसलिए भेद नहीं है। यदि आप व्यक्तिगत नाम चाहते हैं, तो आपको देखना चाहिए Enum.GetNames। - nawfal
फिर यदि आपके पास अपने enum में डुप्लिकेट / समानार्थी हैं, और आप अन्य व्यवहार चाहते हैं, तो आप लिंक का उपयोग कर सकते हैं Distinct एक्सटेंशन (.NET 3.5 के बाद से), तो foreach (var suit in ((Suit[])Enum.GetValues(typeof(Suit))).Distinct()) { }। - Jeppe Stig Nielsen
मैंने उपयोग करने की कोशिश करने की गलती की var प्रकार के लिए। कंपाइलर चर बना देगा Object enum के बजाय। Enum प्रकार स्पष्ट रूप से सूचीबद्ध करें। - jpmc26


यह मुझे लगता है कि आप वास्तव में मूल्यों के बजाय प्रत्येक enum के नाम मुद्रित करना चाहते हैं। कौनसे मामलेमें Enum.GetNames() सही दृष्टिकोण प्रतीत होता है।

public enum Suits
{
    Spades,
    Hearts,
    Clubs,
    Diamonds,
    NumSuits
}

public void PrintAllSuits()
{
    foreach (string name in Enum.GetNames(typeof(Suits)))
    {
        System.Console.WriteLine(name);
    }
}

वैसे, मूल्य बढ़ाना एक enum के मूल्यों को गिनने का एक अच्छा तरीका नहीं है। आपको इसके बजाय ऐसा करना चाहिए।

मै इस्तेमाल करूंगा Enum.GetValues(typeof(Suit)) बजाय।

public enum Suits
{
    Spades,
    Hearts,
    Clubs,
    Diamonds,
    NumSuits
}

public void PrintAllSuits()
{
    foreach (var suit in Enum.GetValues(typeof(Suits)))
    {
        System.Console.WriteLine(suit.ToString());
    }
}

562
2017-09-19 20:39





मैंने आसान enum उपयोग के लिए कुछ एक्सटेंशन किए हैं, शायद कोई इसका उपयोग कर सकता है ...

public static class EnumExtensions
{
    /// <summary>
    /// Gets all items for an enum value.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    public static IEnumerable<T> GetAllItems<T>(this Enum value)
    {
        foreach (object item in Enum.GetValues(typeof(T)))
        {
            yield return (T)item;
        }
    }

    /// <summary>
    /// Gets all items for an enum type.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    public static IEnumerable<T> GetAllItems<T>() where T : struct
    {
        foreach (object item in Enum.GetValues(typeof(T)))
        {
            yield return (T)item;
        }
    }

    /// <summary>
    /// Gets all combined items from an enum value.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value">The value.</param>
    /// <returns></returns>
    /// <example>
    /// Displays ValueA and ValueB.
    /// <code>
    /// EnumExample dummy = EnumExample.Combi;
    /// foreach (var item in dummy.GetAllSelectedItems<EnumExample>())
    /// {
    ///    Console.WriteLine(item);
    /// }
    /// </code>
    /// </example>
    public static IEnumerable<T> GetAllSelectedItems<T>(this Enum value)
    {
        int valueAsInt = Convert.ToInt32(value, CultureInfo.InvariantCulture);

        foreach (object item in Enum.GetValues(typeof(T)))
        {
            int itemAsInt = Convert.ToInt32(item, CultureInfo.InvariantCulture);

            if (itemAsInt == (valueAsInt & itemAsInt))
            {
                yield return (T)item;
            }
        }
    }

    /// <summary>
    /// Determines whether the enum value contains a specific value.
    /// </summary>
    /// <param name="value">The value.</param>
    /// <param name="request">The request.</param>
    /// <returns>
    ///     <c>true</c> if value contains the specified value; otherwise, <c>false</c>.
    /// </returns>
    /// <example>
    /// <code>
    /// EnumExample dummy = EnumExample.Combi;
    /// if (dummy.Contains<EnumExample>(EnumExample.ValueA))
    /// {
    ///     Console.WriteLine("dummy contains EnumExample.ValueA");
    /// }
    /// </code>
    /// </example>
    public static bool Contains<T>(this Enum value, T request)
    {
        int valueAsInt = Convert.ToInt32(value, CultureInfo.InvariantCulture);
        int requestAsInt = Convert.ToInt32(request, CultureInfo.InvariantCulture);

        if (requestAsInt == (valueAsInt & requestAsInt))
        {
            return true;
        }

        return false;
    }
}

Enum खुद को सजाया जाना चाहिए FlagsAttribute

[Flags]
public enum EnumExample
{
    ValueA = 1,
    ValueB = 2,
    ValueC = 4,
    ValueD = 8,
    Combi = ValueA | ValueB
}

287
2018-06-03 12:03



पहली विस्तार विधि के लिए एक लाइनर; यह और आलसी नहीं है। वापस Enum.GetValues ​​(टाइपोफ (टी))। कास्ट <टी> (); - Leyu
वैकल्पिक रूप से आप ऑफ़ टाइप टाइप भी कर सकते हैं: Enum.GetValues ​​(टाइपोफ (टी))। ऑफ टाइप <टी> ()। यह बहुत बुरा है GetValues ​​<T> () का एक सामान्य संस्करण नहीं है, तो यह और भी अधिक चिकना होगा। - jpierson
शायद कोई यह दिखा सकता है कि इन एक्सटेंशन का उपयोग कैसे करें? कंपाइलर Enum EnumExample पर एक्सटेंशन विधियों को नहीं दिखाता है। - Tomas
क्या कोई भी उदाहरण जोड़ सकता है कि उन कार्यों का उपयोग कैसे करें? - Ashwini Verma
पुन: प्रयोज्य कोड के लिए +1: उदाहरण - लाइब्रेरी में इन एक्सटेंशन विधियों को सहेजें और इसे संदर्भित करें [ध्वज] सार्वजनिक enum mytypes {name1, name2}; सूची <string> myTypeNames = mytypes.GetAllItems (); - Krishna


.NET ढांचे के कुछ संस्करण समर्थन नहीं करते हैं Enum.GetValues। यहां से एक अच्छा कामकाज है विचार 2.0: कॉम्पैक्ट फ्रेमवर्क में Enum.GetValues:

public List<Enum> GetValues(Enum enumeration)
{
   List<Enum> enumerations = new List<Enum>();
   foreach (FieldInfo fieldInfo in enumeration.GetType().GetFields(
         BindingFlags.Static | BindingFlags.Public))
   {
      enumerations.Add((Enum)fieldInfo.GetValue(enumeration));
   }
   return enumerations;
}

जैसा कि किसी भी कोड के साथ शामिल है प्रतिबिंब, आपको यह सुनिश्चित करने के लिए कदम उठाने चाहिए कि यह केवल एक बार चलता है और परिणाम कैश किए जाते हैं।


147
2017-09-03 18:48



सूची को तत्काल करने के बजाय यहां उपज कीवर्ड का उपयोग क्यों न करें? - Eric Mickelsen
या छोटा: return type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)).Cast<Enum>(); - nawfal
@nawfal: लिंक उपलब्ध नहीं है .NET CF 2.0। - Gabriel GM
@Ekevoo एमवीसी में DropDownList को इस enum मूल्यों को कैसे बांधें? - Clint Eastwood


मुझे लगता है कि यह अन्य सुझावों की तुलना में अधिक कुशल है क्योंकि GetValues() प्रत्येक बार आपके पास लूप नहीं होता है। यह भी अधिक संक्षेप में है। और आपको एक संकलन-समय त्रुटि मिलती है जो रनटाइम अपवाद नहीं है Suit एक नहीं है enum

EnumLoop<Suit>.ForEach((suit) => {
    DoSomethingWith(suit);
});

EnumLoop यह पूरी तरह से सामान्य परिभाषा है:

class EnumLoop<Key> where Key : struct, IConvertible {
    static readonly Key[] arr = (Key[])Enum.GetValues(typeof(Key));
    static internal void ForEach(Action<Key> act) {
        for (int i = 0; i < arr.Length; i++) {
            act(arr[i]);
        }
    }
}

85
2018-02-02 13:36



इस तरह जेनरिक का उपयोग करने के साथ सावधान। यदि आप उपयोग करने का प्रयास करते हैं EnumLoop कुछ प्रकार के साथ जो enum नहीं है, यह ठीक संकलित करेगा, लेकिन रनटाइम पर अपवाद फेंक देगा। - svick
धन्यवाद, धन्यवाद। रनटाइम अपवाद वास्तव में इस पृष्ठ पर अन्य उत्तरों के साथ होंगे ... इस को छोड़कर क्योंकि मैंने "जहां कुंजी: स्ट्रक्चर, आईकोनर्टेबल" जोड़ा है ताकि आपको ज्यादातर मामलों में संकलन समय त्रुटि मिल सके। - James
नहीं, GetValues ​​() को केवल एक बार फोरच में बुलाया जाता है। - Alex Blokha
जेम्स, मैं आपकी कक्षा को हतोत्साहित करता हूं क्योंकि चालाक लिखना अच्छा होता है लेकिन उत्पादन कोड में कि कई लोग बनाए रखेंगे और अपडेट करेंगे, चालाक अतिरिक्त काम है। यदि यह एक बड़ी बचत करता है या बहुत उपयोग किया जाएगा - तो बचत बड़ी है और लोग इससे परिचित हो जाएंगे - यह इसके लायक है, लेकिन ज्यादातर मामलों में यह कोड को पढ़ने और अपडेट करने की कोशिश करने वाले लोगों को धीमा कर देता है और संभव बनाता है भविष्य में स्रोत कीड़े। कम कोड बेहतर है :) कम जटिलता भी बेहतर है। - Grant M
@ जेम्स क्या आप इस एनम मानों को एमवीसी में ड्रॉपडाउनलिस्ट में बाध्य करने के लिए एक उदाहरण दे सकते हैं? - Clint Eastwood


कोई भी क्यों उपयोग नहीं कर रहा है Cast<T>?

var suits = Enum.GetValues(typeof(Suit)).Cast<Suit>();

तुम वहाँ जाओ IEnumerable<Suit>


82
2018-03-17 04:15



यदि आप LINQ का उपयोग कर सकते हैं तो यह बहुत अच्छा है ... - MemphiZ
यह भी काम करता है from खंड और foreach हेडर घोषणाकर्ता। - Aluan Haddad


आपको नहीं मिलेगा Enum.GetValues() सिल्वरलाइट में

Einar Ingebrigtsen द्वारा मूल ब्लॉग पोस्ट:

public class EnumHelper
{
    public static T[] GetValues<T>()
    {
        Type enumType = typeof(T);

        if (!enumType.IsEnum)
        {
            throw new ArgumentException("Type '" + enumType.Name + "' is not an enum");
        }

        List<T> values = new List<T>();

        var fields = from field in enumType.GetFields()
                     where field.IsLiteral
                     select field;

        foreach (FieldInfo field in fields)
        {
            object value = field.GetValue(enumType);
            values.Add((T)value);
        }

        return values.ToArray();
    }

    public static object[] GetValues(Type enumType)
    {
        if (!enumType.IsEnum)
        {
            throw new ArgumentException("Type '" + enumType.Name + "' is not an enum");
        }

        List<object> values = new List<object>();

        var fields = from field in enumType.GetFields()
                     where field.IsLiteral
                     select field;

        foreach (FieldInfo field in fields)
        {
            object value = field.GetValue(enumType);
            values.Add(value);
        }

        return values.ToArray();
    }
}

68
2017-11-17 01:29



अच्छा समाधान, लेकिन कुछ रिफैक्टरिंग बेहतर होगा! :) - nawfal
@AubreyTaylor क्या आप इस एनम मानों को एमवीसी में ड्रॉपडाउनलिस्ट में बाध्य करने के लिए एक उदाहरण दे सकते हैं? - Clint Eastwood
मैं .NET Framework 4.0 और Silverlight enum.getvalues ​​काम का उपयोग कर रहा हूं, मैं जिस कोड का उपयोग करता हूं वह है ---> enum.GetValues ​​(typeof (enum)) - Ananda
सी # 7.3 से शुरू (विजुअल स्टूडियो 2017 ≥ v15.7), कोई भी उपयोग कर सकता है where T: Enum - Yahoo Serious


बस मेरा समाधान जोड़ने के लिए, जो कॉम्पैक्ट फ्रेमवर्क (3.5) में काम करता है और प्रकार की जांच का समर्थन करता है संकलन समय पर:

public static List<T> GetEnumValues<T>() where T : new() {
    T valueType = new T();
    return typeof(T).GetFields()
        .Select(fieldInfo => (T)fieldInfo.GetValue(valueType))
        .Distinct()
        .ToList();
}

public static List<String> GetEnumNames<T>() {
    return typeof (T).GetFields()
        .Select(info => info.Name)
        .Distinct()
        .ToList();
}

- अगर कोई जानता है कि कैसे छुटकारा पाएं T valueType = new T(), मुझे एक समाधान देखने में खुशी होगी।

एक कॉल इस तरह दिखेगा:

List<MyEnum> result = Utils.GetEnumValues<MyEnum>();

50
2017-07-07 13:37



उपयोग करने के बारे में क्या T valueType = default(T)? - Oliver
बढ़िया, मुझे वह कीवर्ड भी नहीं पता था। कुछ नया सीखना हमेशा अच्छा लगा। धन्यवाद! क्या यह हमेशा एक ही ऑब्जेक्ट का संदर्भ देता है, या जब भी डिफ़ॉल्ट कथन कहा जाता है तो यह एक नया उदाहरण बनाता है? मुझे इस बारे में नेट पर कुछ भी नहीं मिला है, लेकिन अगर यह हर बार एक नया उदाहरण बनाता है, तो यह उस उद्देश्य को हरा देता है जिसे मैं ढूंढ रहा था (एक लाइनर ^^)। - Mallox
.GetValue (नया टी ())? - Jason Miesionczek
क्या यह गणना पर हर पुनरावृत्ति के लिए एक नया उदाहरण नहीं बनाएगा? - Mallox
-1 "संकलन समय पर प्रकार की जांच का समर्थन करता है:"। किस प्रकार की जांच? यह किसी के लिए काम करेगा new()  T। इसके अलावा, आपको जरूरत नहीं है new T()बिलकुल, आप केवल स्थिर फ़ील्ड का चयन कर सकते हैं और कर सकते हैं .GetValue(null)। औब्रे का जवाब देखें। - nawfal


मुझे लगता है कि आप इसका उपयोग कर सकते हैं

Enum.GetNames(Suit)

44
2017-09-19 20:37



Enum.GetValues ​​(सूट) - Ian Boyd


public void PrintAllSuits()
{
    foreach(string suit in Enum.GetNames(typeof(Suits)))
    {
        Console.WriteLine(suit);
    }
}

42
2017-09-19 21:05



यह एक स्ट्रिंग को गिनती करता है, उन चीज़ों को वापस गणना मूल्य में परिवर्तित करना न भूलें ताकि गणना की गणना की जा सके। - Ian Boyd
मैं आपके संपादन से देखता हूं कि आप वास्तव में enums पर काम करना चाहते हैं, उपरोक्त कोड ने आपकी मूल पोस्ट को संबोधित किया है। - Joshua Drake