कैसे एक एनुम को एन्यूमरेट करें


3763

आप enumC # में कैसे एन्युमरेट कर सकते हैं ?

उदाहरण के लिए निम्नलिखित कोड संकलित नहीं करता है:

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

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

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

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

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


17
इन्हें भी देखें ... stackoverflow.com/questions/972307/…
स्टीवके

2
आप C #
एनम

जवाबों:


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

नोट : कलाकारों को (Suit[])कड़ाई से आवश्यक नहीं है, लेकिन यह कोड 0.5 एनएस को तेज बनाता है


97
यदि आपके पास एन्यूमरेटर सूची में डुप्लिकेट मान हैं, तो यह काम नहीं करता है।
जेसी

10
मैं सिर्फ यह बताना चाहता हूं कि यह दुर्भाग्य से चांदी की रोशनी में काम नहीं करेगा, क्योंकि चांदी की लाइब्रेरी में शामिल नहीं है enum.GetValues। आपको इस मामले में प्रतिबिंब का उपयोग करना होगा।
जियाकोमो टैगलीब्यू

146
@ यह डुप्लीकेट स्थितियों की तरह काम करता हैenum E {A = 0, B = 0}Enum.GetValuesदो मूल्यों में परिणाम लौटाए जा रहे हैं, हालांकि वे समान हैं। E.A == E.Bसच है, इसलिए भेद नहीं है। यदि आप व्यक्तिगत नाम चाहते हैं, तो आपको तलाश करनी चाहिए Enum.GetNames
नवफाल

13
फिर यदि आपके पास आपके एनम में डुप्लिकेट / समानार्थी शब्द हैं, और आप अन्य व्यवहार चाहते हैं, तो आप Linq के Distinctएक्सटेंशन (.NET 3.5 के बाद से) का उपयोग कर सकते हैं , इसलिए foreach (var suit in ((Suit[])Enum.GetValues(typeof(Suit))).Distinct()) { }
जेपी स्टिग नील्सन

42
मैंने varटाइप के लिए उपयोग करने की कोशिश की गलती की । कंपाइलर Objectएनम के बजाय वेरिएबल बनाएगा । स्पष्ट रूप से एनम टाइप करें।
jpmc26

695

यह मुझे ऐसा लगता है जैसे आप वास्तव में मूल्यों के बजाय प्रत्येक एनम के नामों को प्रिंट करना चाहते हैं। जिस मामले में 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.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());
    }
}

2
VB सिंटेक्स यहाँ: लिंक
AndruWitta

मैंने आपकी ओर से एक छोटे से परिवर्तन के साथ आपका संस्करण लिया Enum.GetValues(typeof(Suits)).OfType<Suits>().ToArray():। उस स्थिति में मैं Suitsएनम आइटम की सरणी को पुनरावृत्त कर सकता हूं , तार नहीं।
बरबस

@ बरबस सिर्फ क्यों नहीं Suits suit in Enum.GetValues(typeof(Suits))?
थीडकिंग

@themadking ओह, यार! बेशक, सटीक प्रकार का उपयोग करना श के इस राक्षसी टुकड़े से बेहतर लगता है ... कोड!
बाराबस

337

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

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

एनुम को ही फ्लैगसैटर से सजाया जाना चाहिए :

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

13
पहले विस्तार विधि के लिए एक लाइनर; यह अधिक आलसी नहीं है। वापसी Enum.GetValues ​​(टाइपोफ़ (टी))। कास्ट <टी> ();
लीयू

2
वैकल्पिक रूप से आप टाइप का भी उपयोग कर सकते हैं: Enum.GetValues ​​(टाइपोफ़ (टी))। टाइप <टी> ()। यह बहुत बुरा है GetValues ​​<T> () का एक सामान्य संस्करण नहीं है तो यह और भी अधिक चालाक होगा।
जिपरसन

3
हो सकता है कि कोई व्यक्ति यह बता सके कि इन एक्सटेंशन का उपयोग कैसे किया जाए? कंपाइलर Enum EnumExample पर विस्तार विधियाँ नहीं दिखाता है।
टॉमस

1
क्या कोई उदाहरण जोड़ सकता है कि उन कार्यों का उपयोग कैसे किया जाए?
अश्विनी वर्मा

3
पुन: प्रयोज्य कोड के लिए +1: उदाहरण - इन विस्तार विधियों को एक पुस्तकालय में सहेजें और इसे संदर्भ दें [झंडे] सार्वजनिक enum mytypes {name1, name2}; सूची <string> myTypeNames = mytypes.GetAllItems ();
कृष्णा

178

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

public Enum[] GetValues(Enum enumeration)
{
    FieldInfo[] fields = enumeration.GetType().GetFields(BindingFlags.Static | BindingFlags.Public);
    Enum[] enumerations = new Enum[fields.Length];

    for (var i = 0; i < fields.Length; i++)
        enumerations[i] = (Enum) fields[i].GetValue(enumeration);

    return enumerations;
}

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


18
किसी सूची को त्वरित करने के बजाय यहां उपज कीवर्ड का उपयोग क्यों न करें?
एरिक मिकेलसेन

1
या उससे कम:return type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)).Cast<Enum>();
नवाफल

7
@nawfal: Linq उपलब्ध नहीं है .net CF 2.0।
गेब्रियल जीएम

@Ekevoo इस एनम वैल्यू को एमवीसी में ड्रॉपडाउनलिस्ट के साथ कैसे बांधा जाए?
जैक

115

उपयोग करें Cast<T>:

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

आप वहाँ जाना है, IEnumerable<Suit>


1
यह fromक्लॉज और foreachहेडर घोषणाकर्ता में भी काम करता है ।
अलुआन हद्दाद

97

मुझे लगता है कि यह अन्य सुझावों की तुलना में अधिक कुशल है क्योंकि 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]);
        }
    }
}

6
इस तरह से जेनेरिक का उपयोग करने के साथ सावधान। यदि आप EnumLoopकिसी ऐसे प्रकार के साथ उपयोग करने का प्रयास करते हैं जो एक एनम नहीं है, तो यह ठीक संकलन करेगा, लेकिन रनटाइम पर एक अपवाद फेंकें।
12

7
धन्यवाद svick रनटाइम अपवाद वास्तव में इस पृष्ठ पर अन्य उत्तरों के साथ होगा ... इस एक को छोड़कर क्योंकि मैंने "जहां कुंजी: संरचना, असंगत" को जोड़ा है ताकि आपको ज्यादातर मामलों में एक संकलन समय त्रुटि मिल सके।
जेम्स

3
नहीं, GetValues ​​() को केवल एक बार फ़ॉर्च में कहा जाता है।
एलेक्स ब्लोखा

4
जेम्स, मैं आपकी कक्षा को हतोत्साहित करूंगा क्योंकि चतुर लिखने में अच्छा है लेकिन उत्पादन कोड में जो कई लोग बनाए रखेंगे और अपडेट करेंगे, चतुर अतिरिक्त काम है। यदि यह एक बड़ी बचत करता है या इसका बहुत उपयोग किया जाएगा - तो बचत बड़ी है और लोग इससे परिचित होंगे - यह इसके लायक है, लेकिन ज्यादातर मामलों में यह कोड को पढ़ने और अपडेट करने की कोशिश कर रहे लोगों को धीमा कर देता है और एक संभव परिचय देता है भविष्य में स्रोत कीड़े। कम कोड बेहतर है :) कम जटिलता भी बेहतर है।
ग्रांट एम

2
@ ग्रीनम क्यों? यह कोड न तो जटिल है, और यह अविश्वसनीय रूप से छोटा है। उसके ऊपर, कक्षा को एक बार लिखने से कोड के छोटे पुनरावृत्तियों का उपयोग करने की अनुमति उसके उदाहरण के अनुसार होगी। यह बेहद साफ है, अगर आप उस कोड को अपडेट नहीं कर सकते हैं, तो आप शायद किसी भी कंपनी के कोड को अपडेट नहीं कर सकते।
डिस्पर्सिया

77

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

मूल ब्लॉग पोस्ट आइंर इंजीब्रिजत्सेन द्वारा :

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

2
अच्छा समाधान है, लेकिन कुछ refactoring बेहतर होगा! :)
नवफाल

मैं .NET फ्रेमवर्क 4.0 और सिल्वरलाइट Enum.getvalues ​​काम का उपयोग कर रहा हूं, मैंने जो कोड उपयोग किया है वह है ---> enum.GetValues ​​(टाइपोफ (enum))
आनंद

2
C # 7.3 (विजुअल स्टूडियो 2017 C v15.7) के साथ शुरू, कोई भी उपयोग कर सकता हैwhere T: Enum
Yahoo Serious

59

मेरा समाधान .NET कॉम्पैक्ट फ्रेमवर्क (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>();

2
उपयोग करने के बारे में क्या T valueType = default(T)?
ओलिवर

महान, मुझे वह कीवर्ड भी नहीं पता था। हमेशा कुछ नया सीखने के लिए अच्छा है। धन्यवाद! क्या यह हमेशा एक ही वस्तु के लिए एक संदर्भ देता है, या क्या यह एक नया उदाहरण प्रत्येक बार डिफ़ॉल्ट स्टेटमेंट कहलाता है? मुझे अब तक इस बारे में नेट पर कुछ भी नहीं मिला है, लेकिन अगर यह हर बार एक नया उदाहरण बनाता है, तो यह उस उद्देश्य को हरा देता है जिसकी मुझे तलाश थी (एक-लाइनर ^ ^ होने के लिए)।
मैलोक्स

1
क्या यह गणना पर हर पुनरावृत्ति के लिए एक नया उदाहरण नहीं बनाएगा?
मालोक्स

1
-1 "संकलित समय पर प्रकार की जाँच का समर्थन करता है:"। किस प्रकार की जाँच? यह किसी के लिए भी काम करेगा new() T। इसके अलावा, आप की जरूरत नहीं है new T(), आप केवल स्थिर क्षेत्रों का चयन कर सकते हैं और करते हैं .GetValue(null)। देखें ऑब्रे का जवाब।
नवाफाल

2
C # 7.3 (विजुअल स्टूडियो 2017 C v15.7) के साथ शुरू, कोई भी उपयोग कर सकता हैwhere T: Enum
Yahoo Serious


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

2
यह एक स्ट्रिंग की गणना करता है, उन चीजों को एक एन्यूमरेशन मान में परिवर्तित करने के लिए मत भूलना ताकि एन्यूमरेशन को एन्यूमरेट किया जा सके।
इयान बॉयड

1
मैं आपके संपादन से देख रहा हूं कि आप वास्तव में स्वयं एनमों पर काम करना चाहते हैं, उपरोक्त कोड ने आपके मूल पोस्ट को संबोधित किया है।
जोशुआ ड्रेक

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

मैंने अस्पष्ट अफवाहें सुनी हैं कि यह बहुत धीमा है। किसी को पता है? - ओरियन एडवर्ड्स 15 अक्टूबर '08 को 1:31 7 बजे

मुझे लगता है कि कैशिंग से सरणी में काफी तेजी आएगी। ऐसा लगता है कि आप हर बार एक नई सरणी (प्रतिबिंब के माध्यम से) प्राप्त कर रहे हैं। बल्कि:

Array enums = Enum.GetValues(typeof(Suit));
foreach (Suit suitEnum in enums) 
{
    DoSomething(suitEnum);
}

यह कम से कम थोड़ा तेज है, जा?


5
संकलक को इस बात का ध्यान रखना चाहिए, हालांकि।
Stephan Bijzitter 12

@StephanBijzitter वाह, आप इस एक पर बहुत दूर पढ़ रहे हैं :-) मैं सहमत हूं, संकलक को मेरे समाधान को अनावश्यक बनाना चाहिए।
सीमित प्रायश्चित

1
यह आवश्यक नहीं है। ILSpy में संकलित कोड को देखते हुए, संकलनकर्ता निश्चित रूप से पहले से ही ऐसा करता है। क्यों इस जवाब को बिल्कुल कम, 35 बार कम किया गया है?
mhenry1384

1
इसे बहुत पहले उखाड़ा गया था। बहुत समय पहले। मैं दांव लगाऊंगा कि संकलक ने इस बैक को तब भी हल किया होगा, हालांकि। लेकिन यह यकीन है कि अधिक प्रदर्शन करता है, है ना? ;-)
सीमित प्रायश्चित

32

तीन तरीके से:

  1. Enum.GetValues(type) // चूंकि .NET 1.1, सिल्वरलाइट या .NET कॉम्पैक्ट फ्रेमवर्क में नहीं है
  2. type.GetEnumValues() // केवल .NET 4 और इसके बाद के संस्करण पर
  3. type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)) // हर जगह काम करता है

मुझे यकीन नहीं है कि GetEnumValuesटाइप इंस्टेंस पर क्यों पेश किया गया था। यह मेरे लिए बिल्कुल भी पठनीय नहीं है।


एक सहायक वर्ग की तरह Enum<T>मेरे लिए सबसे पठनीय और यादगार है:

public static class Enum<T> where T : struct, IComparable, IFormattable, IConvertible
{
    public static IEnumerable<T> GetValues()
    {
        return (T[])Enum.GetValues(typeof(T));
    }

    public static IEnumerable<string> GetNames()
    {
        return Enum.GetNames(typeof(T));
    }
}

अब आप कॉल करें:

Enum<Suit>.GetValues();

// Or
Enum.GetValues(typeof(Suit)); // Pretty consistent style

यदि प्रदर्शन मायने रखता है तो कोई भी किसी प्रकार के कैशिंग का उपयोग कर सकता है, लेकिन मुझे इस बात की बिल्कुल भी उम्मीद नहीं है।

public static class Enum<T> where T : struct, IComparable, IFormattable, IConvertible
{
    // Lazily loaded
    static T[] values;
    static string[] names;

    public static IEnumerable<T> GetValues()
    {
        return values ?? (values = (T[])Enum.GetValues(typeof(T)));
    }

    public static IEnumerable<string> GetNames()
    {
        return names ?? (names = Enum.GetNames(typeof(T)));
    }
}

यह विधियों का एक अच्छा सारांश है। मुझे लगता है कि आपको अपने दूसरे उत्तर को इस में मिलाना चाहिए। सच्चाई यह है कि एनम विशेष हैं और उनके माध्यम से लूपिंग अक्सर (आमतौर पर) केवल एन्यूमरेशन के रूप में मान्य है क्योंकि आप जानते हैं कि मान कभी नहीं बदलेंगे। IOW, यदि आपके पास एक एनम है जो हर समय बदल रहा है तो आपने शुरू करने के लिए गलत डेटा निर्माण को चुना है।
krowe2

31

बस शीर्ष उत्तरों को जोड़कर, मैंने एक बहुत ही सरल विस्तार को एक साथ फेंक दिया:

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 T value) where T : Enum
    {
        return (T[])Enum.GetValues(typeof (T));
    }
}

यह @ जेपी-स्टिग-नीलसन की टिप्पणी से तेज, साफ, सरल और तेज है।


6
C # 7.3 (विजुअल स्टूडियो 2017 C v15.7) के साथ शुरू, कोई भी उपयोग कर सकता हैwhere T: Enum
याहू सीरियस

24

इसे पुनरावृत्त करने के दो तरीके हैं Enum:

1. var values =  Enum.GetValues(typeof(myenum))
2. var values =  Enum.GetNames(typeof(myenum))

पहला आपको ** object** s के एक सरणी पर फॉर्म में मान देगा , और दूसरा आपको ** String** के सरणी के रूप में मान देगा ।

foreachनीचे दिए गए लूप में इसका उपयोग करें :

foreach(var value in values)
{
    // Do operations here
}

2
शायद 'क्योंकि यह पहले से ही कई जवाबों में शामिल है? चलिए जवाब बेमानी नहीं बनाते।
नवफल

@nawfal हां अन्य उत्तरों में शामिल हो सकती है, हालांकि उनमें से अधिकांश में अच्छी तरह से निष्कर्ष नहीं निकाला गया है।
Kylo Ren

23

मैं ToString () का उपयोग करता हूं और फ़्लैग में थूक सरणी को विभाजित और पार्स करता हूं।

[Flags]
public enum ABC {
   a = 1,
   b = 2,
   c = 4
};

public IEnumerable<ABC> Getselected (ABC flags)
{
   var values = flags.ToString().Split(',');
   var enums = values.Select(x => (ABC)Enum.Parse(typeof(ABC), x.Trim()));
   return enums;
}

ABC temp= ABC.a | ABC.b;
var list = getSelected (temp);
foreach (var item in list)
{
   Console.WriteLine(item.ToString() + " ID=" + (int)item);
}

17

मैं यह नहीं मानता कि यह बेहतर है, या अच्छा भी है। मैं अभी एक और उपाय बता रहा हूं।

यदि एनम मान 0 से n - 1 तक सख्ती से है, तो एक सामान्य विकल्प है:

public void EnumerateEnum<T>()
{
    int length = Enum.GetValues(typeof(T)).Length;
    for (var i = 0; i < length; i++)
    {
        var @enum = (T)(object)i;
    }
}

यदि enum मान सन्निहित हैं और आप enum का पहला और अंतिम तत्व प्रदान कर सकते हैं, तो:

public void EnumerateEnum()
{
    for (var i = Suit.Spade; i <= Suit.Diamond; i++)
    {
        var @enum = i;
    }
}

लेकिन यह कड़ाई से पर्याप्त नहीं है, सिर्फ लूपिंग। दूसरी विधि किसी भी अन्य दृष्टिकोण की तुलना में बहुत तेज है, हालांकि ...


16

यदि आपको निर्माण और चलाने के समय गति और प्रकार की जाँच की आवश्यकता है, तो यह सहायक विधि प्रत्येक तत्व को डालने के लिए LINQ का उपयोग करने से बेहतर है:

public static T[] GetEnumValues<T>() where T : struct, IComparable, IFormattable, IConvertible
{
    if (typeof(T).BaseType != typeof(Enum))
    {
        throw new ArgumentException(string.Format("{0} is not of type System.Enum", typeof(T)));
    }
    return Enum.GetValues(typeof(T)) as T[];
}

और आप इसे नीचे की तरह उपयोग कर सकते हैं:

static readonly YourEnum[] _values = GetEnumValues<YourEnum>();

बेशक आप लौट सकते हैं IEnumerable<T>, लेकिन यह आपको यहाँ कुछ नहीं खरीदता है।


3
C # 7.3 (विजुअल स्टूडियो 2017 C v15.7) के साथ शुरू, कोई भी उपयोग कर सकता हैwhere T: Enum
याहू सीरियस

14

यहाँ DDL के लिए चुनिंदा विकल्प बनाने का एक कार्य उदाहरण दिया गया है :

var resman = ViewModelResources.TimeFrame.ResourceManager;

ViewBag.TimeFrames = from MapOverlayTimeFrames timeFrame
      in Enum.GetValues(typeof(MapOverlayTimeFrames))
      select new SelectListItem
      {
         Value = timeFrame.ToString(),
         Text = resman.GetString(timeFrame.ToString()) ?? timeFrame.ToString()
      };

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

(वर्तमान स्वीकृत उत्तर में एक कास्ट है जो मुझे नहीं लगता है कि इसकी आवश्यकता है (हालांकि मैं गलत हो सकता हूं)।)


10

यह प्रश्न " सी # स्टेप बाय स्टेप 2013 " के अध्याय 10 में दिखाई देता है " के

लेखक Enumerators (कार्ड का एक पूर्ण डेक बनाने के लिए) की एक जोड़ी के माध्यम से पुनरावृति करने के लिए एक डबल-लूप का उपयोग करता है:

class Pack
{
    public const int NumSuits = 4;
    public const int CardsPerSuit = 13;
    private PlayingCard[,] cardPack;

    public Pack()
    {
        this.cardPack = new PlayingCard[NumSuits, CardsPerSuit];
        for (Suit suit = Suit.Clubs; suit <= Suit.Spades; suit++)
        {
            for (Value value = Value.Two; value <= Value.Ace; value++)
            {
                cardPack[(int)suit, (int)value] = new PlayingCard(suit, value);
            }
        }
    }
}

इस मामले में, Suitऔर Valueदोनों गणना हैं:

enum Suit { Clubs, Diamonds, Hearts, Spades }
enum Value { Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King, Ace}

और PlayingCardएक परिभाषित के साथ एक कार्ड वस्तु है Suitऔर Value:

class PlayingCard
{
    private readonly Suit suit;
    private readonly Value value;

    public PlayingCard(Suit s, Value v)
    {
        this.suit = s;
        this.value = v;
    }
}

क्या यह काम करेगा यदि एनम में मान अनुक्रमिक नहीं हैं?
आमिर मसूद


8

क्या होगा यदि आप जानते हैं कि प्रकार एक होगा enum, लेकिन आप नहीं जानते कि संकलन के समय सटीक प्रकार क्या है?

public class EnumHelper
{
    public static IEnumerable<T> GetValues<T>()
    {
        return Enum.GetValues(typeof(T)).Cast<T>();
    }

    public static IEnumerable getListOfEnum(Type type)
    {
        MethodInfo getValuesMethod = typeof(EnumHelper).GetMethod("GetValues").MakeGenericMethod(type);
        return (IEnumerable)getValuesMethod.Invoke(null, null);
    }
}

विधि getListOfEnumकिसी भी एनुम प्रकार को लेने के लिए प्रतिबिंब का उपयोग करती है और IEnumerableसभी एनम मानों को वापस करती है।

उपयोग:

Type myType = someEnumValue.GetType();

IEnumerable resultEnumerable = getListOfEnum(myType);

foreach (var item in resultEnumerable)
{
    Console.WriteLine(String.Format("Item: {0} Value: {1}",item.ToString(),(int)item));
}

8

एक सरल और सामान्य तरीका है कि आप जो कुछ बातचीत कर सकते हैं उसे एक एनम में परिवर्तित करें:

public static Dictionary<int, string> ToList<T>() where T : struct
{
   return ((IEnumerable<T>)Enum
       .GetValues(typeof(T)))
       .ToDictionary(
           item => Convert.ToInt32(item),
           item => item.ToString());
}

और तब:

var enums = EnumHelper.ToList<MyEnum>();

A Dictionaryएक अच्छा विचार नहीं है: यदि आपके पास एक Enumपसंद है enum E { A = 0, B = 0 }, तो 0 मान को उत्पन्न करने के लिए 2 बार जोड़ा जाता है ArgumentException(आप 2 या अधिक बार उसी Keyको जोड़ नहीं सकते Dictionary!)।
मैसिमिलियानो क्रूस

क्यों Dictionary<,>नाम विधि से वापसी ToList? साथ ही क्यों नहीं लौटे Dictionary<T, string>?
अलुआन हदद

8

public static IEnumerable<T> GetValues<T>()अपनी कक्षा में विधि जोड़ें , जैसे:

public static IEnumerable<T> GetValues<T>()
{
    return Enum.GetValues(typeof(T)).Cast<T>();
}

कॉल करें और अपना एनम पास करें। अब आप इसका उपयोग करके इसे पुन foreach: व्यवस्थित कर सकते हैं :

 public static void EnumerateAllSuitsDemoMethod()
 {
     // Custom method
     var foos = GetValues<Suit>();
     foreach (var foo in foos)
     {
         // Do something
     }
 }

2

enumप्रकारों को "गणना प्रकार" कहा जाता है, क्योंकि वे कंटेनर होते हैं जो "गणना" (जो वे नहीं कर रहे हैं) मान लेते हैं, लेकिन क्योंकि वे उस प्रकार के एक चर के लिए संभावित मूल्यों की गणना करके परिभाषित किए जाते हैं ।

(वास्तव में, यह उससे थोड़ा अधिक जटिल है - इनम प्रकारों को "अंतर्निहित" पूर्णांक प्रकार माना जाता है, जिसका अर्थ है कि प्रत्येक एनम मान एक पूर्णांक मान से मेल खाता है (यह आमतौर पर निहित है, लेकिन मैन्युअल रूप से निर्दिष्ट किया जा सकता है)। एक तरह से ताकि आप उस प्रकार के किसी भी पूर्णांक को एनम चर में रख सकें , भले ही वह "नामित" मान न हो।)

System.Enum.GetNames विधि , तार जो enum मूल्यों के नाम हैं की एक सरणी को पुनः प्राप्त किया जा सकता है जैसा कि नाम से पता चलता है।

संपादित करें: इसके बजाय System.Enum.GetValues विधि का सुझाव देना चाहिए । उफ़।


2
यद्यपि आपका उत्तर अपने आप में सही है, लेकिन यह वास्तव में ओपी के मूल प्रश्न को संबोधित नहीं करता है। GetNamesविधि रिटर्न, वास्तव में, एक स्ट्रिंग सरणी, लेकिन ओ पी मूल्यों के माध्यम से एक प्रगणक की आवश्यकता है।
सिल्वियु प्रेडा

@ सिल्वीउप्रेडा: संपादित। यह GetNames के बजाय GetValues ​​होना चाहिए था।
एमिली चेन

2

मैंने कई तरीकों की कोशिश की और इस कोड से परिणाम मिला:

एनम से इंट की सूची प्राप्त करने के लिए, निम्नलिखित का उपयोग करें। यह काम करता हैं!

List<int> listEnumValues = new List<int>();
YourEnumType[] myEnumMembers = (YourEnumType[])Enum.GetValues(typeof(YourEnumType));
foreach ( YourEnumType enumMember in myEnumMembers)
{
    listEnumValues.Add(enumMember.GetHashCode());
}

1
tanx for edit @ peter-mortensen
reza akhlaghi

0

इसके अलावा, आप प्रतिबिंब का उपयोग करके सीधे एनम के सार्वजनिक स्थिर सदस्यों को बांध सकते हैं:

typeof(Suit).GetMembers(BindingFlags.Public | BindingFlags.Static)
    .ToList().ForEach(x => DoSomething(x.Name));

0

यदि आपके पास है:

enum Suit
{
   Spades,
   Hearts,
   Clubs,
   Diamonds
}

इस:

foreach (var e in Enum.GetValues(typeof(Suit)))
{
    Console.WriteLine(e.ToString() + " = " + (int)e);
}

उत्पादन होगा:

Spades = 0
Hearts = 1
Clubs = 2
Diamonds = 3

0

LINQ जेनेरिक तरीका:

    public static Dictionary<int, string> ToList<T>() where T : struct =>
        ((IEnumerable<T>)Enum.GetValues(typeof(T))).ToDictionary(value => Convert.ToInt32(value), value => value.ToString());

उपयोग:

        var enums = ToList<Enum>();
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.