सी # एक Enum के माध्यम से Iterating? (एक System.Array अनुक्रमणिका)


113

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

// Obtain the string names of all the elements within myEnum 
String[] names = Enum.GetNames( typeof( myEnum ) );

// Obtain the values of all the elements within myEnum 
Array values = Enum.GetValues( typeof( myEnum ) );

// Print the names and values to file
for ( int i = 0; i < names.Length; i++ )
{
    print( names[i], values[i] ); 
}

हालाँकि, मैं मूल्यों को अनुक्रमित नहीं कर सकता। क्या इसे करने का कोई आसान रास्ता है?

या मैं पूरी तरह से कुछ याद किया है!

जवाबों:


204
Array values = Enum.GetValues(typeof(myEnum));

foreach( MyEnum val in values )
{
   Console.WriteLine (String.Format("{0}: {1}", Enum.GetName(typeof(MyEnum), val), val));
}

या, आप System.Array को लौटा सकते हैं:

string[] names = Enum.GetNames(typeof(MyEnum));
MyEnum[] values = (MyEnum[])Enum.GetValues(typeof(MyEnum));

for( int i = 0; i < names.Length; i++ )
{
    print(names[i], values[i]);
}

लेकिन, क्या आप सुनिश्चित हो सकते हैं कि GetValues ​​उसी क्रम में मान लौटाएं जैसे GetNames नाम वापस करते हैं?


3
"लेकिन, क्या आप सुनिश्चित हो सकते हैं कि GetValues ​​उसी क्रम में मान लौटाते हैं जैसे GetNames नाम लौटाते हैं?" - यह एक बहुत अच्छी बात है और मुझे अभी तक कुछ पता नहीं है! मुझे लगता है कि आपका पहला समाधान संभवतः मूल्यों और तार को मज़बूती से मिलान करने का एक तरीका प्रदान करेगा
टीके।

नमस्कार, मैंने ऐसा करने से पहले "सूचकांक-बेमेल" होने के संदेह के बारे में उल्लेख किया है; हालाँकि, मुझे अभी तक पता नहीं चला है कि क्या यह वास्तव में एक चिंता है या नहीं? क्या कोई निश्चित मामले हैं, जिससे यह धारणा भड़क सकती है? धन्यवाद!
फनका

आप शायद दूसरे "वैल" को एक इंट में डालना चाहते हैं, यदि आप मूल्य बेमेल का निवारण करना चाहते हैं Enum.GetName(typeof(MyEnum), val), (int)val)जिसमें आउटपुट एन्यूमरेशन नाम और संख्या प्रदान करता है।
ग्रेग

GetValues ​​और GetNames एक ही क्रम में लौटते हैं, अर्थात्: "वापसी मान सरणी के तत्वों को एन्यूमरेटेड स्थिरांक के द्विआधारी मूल्यों (जैसे कि उनके अहस्ताक्षरित परिमाण द्वारा) द्वारा क्रमबद्ध किया जाता है।"
रसेल बोरोगोव

मेरा मानना है कि आप भी LINQ उपयोग कर सकते हैं सीधे फोन करके Cast<T>परिणाम पर:Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>()...
jocull

33

आपको सरणी डालने की आवश्यकता है - लौटाया गया सरणी वास्तव में अनुरोधित प्रकार का है, अर्थात myEnum[]यदि आप मांगते हैं typeof(myEnum):

myEnum[] values = (myEnum[]) Enum.GetValues(typeof(myEnum));

फिर values[0]आदि


9

आप उस Array को विभिन्न प्रकार के Arrays में डाल सकते हैं:

myEnum[] values = (myEnum[])Enum.GetValues(typeof(myEnum));

या यदि आप पूर्णांक मान चाहते हैं:

int[] values = (int[])Enum.GetValues(typeof(myEnum));

आप पाठ्यक्रम के उन डाले हुए सरणियों को पुनरावृत्त कर सकते हैं :)


7

एक शब्दकोश सूची के बारे में कैसे?

Dictionary<string, int> list = new Dictionary<string, int>();
foreach( var item in Enum.GetNames(typeof(MyEnum)) )
{
    list.Add(item, (int)Enum.Parse(typeof(MyEnum), item));
}

और निश्चित रूप से आप शब्दकोश मान को बदल सकते हैं जो आपके एनम मान हैं।


मुझे लगता है कि यह जाने का रास्ता होगा, लेकिन दुर्भाग्य से एनम कोड के एक क्षेत्र में है जिस पर मेरा कोई नियंत्रण नहीं है!
टी.के.

1
एकमात्र समाधान मैंने पाया है कि वास्तविक पूर्णांक एनम मान प्राप्त करता है!
SharpC

5

दिलचस्प संभावनाओं के साथ एक और समाधान:

enum Days { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }

static class Helpers
{
public static IEnumerable<Days> AllDays(Days First)
{
  if (First == Days.Monday)
  {
     yield return Days.Monday;
     yield return Days.Tuesday;
     yield return Days.Wednesday;
     yield return Days.Thursday;
     yield return Days.Friday;
     yield return Days.Saturday;
     yield return Days.Sunday;
  } 

  if (First == Days.Saturday)
  {
     yield return Days.Saturday;
     yield return Days.Sunday;
     yield return Days.Monday;
     yield return Days.Tuesday;
     yield return Days.Wednesday;
     yield return Days.Thursday;
     yield return Days.Friday;
  } 
}

4

यहाँ एक और है। हमें अपने EnumValues ​​के लिए अनुकूल नाम प्रदान करने की आवश्यकता थी। हमने प्रत्येक Enum मान के लिए एक कस्टम स्ट्रिंग मान दिखाने के लिए System.ComponentModel.DescriptionAttribute का उपयोग किया।

public static class StaticClass
{
    public static string GetEnumDescription(Enum currentEnum)
    {
        string description = String.Empty;
        DescriptionAttribute da;

        FieldInfo fi = currentEnum.GetType().
                    GetField(currentEnum.ToString());
        da = (DescriptionAttribute)Attribute.GetCustomAttribute(fi,
                    typeof(DescriptionAttribute));
        if (da != null)
            description = da.Description;
        else
            description = currentEnum.ToString();

        return description;
    }

    public static List<string> GetEnumFormattedNames<TEnum>()
    {
        var enumType = typeof(TEnum);
        if (enumType == typeof(Enum))
            throw new ArgumentException("typeof(TEnum) == System.Enum", "TEnum");

        if (!(enumType.IsEnum))
            throw new ArgumentException(String.Format("typeof({0}).IsEnum == false", enumType), "TEnum");

        List<string> formattedNames = new List<string>();
        var list = Enum.GetValues(enumType).OfType<TEnum>().ToList<TEnum>();

        foreach (TEnum item in list)
        {
            formattedNames.Add(GetEnumDescription(item as Enum));
        }

        return formattedNames;
    }
}

उपयोग में

 public enum TestEnum
 { 
        [Description("Something 1")]
        Dr = 0,
        [Description("Something 2")]
        Mr = 1
 }



    static void Main(string[] args)
    {

        var vals = StaticClass.GetEnumFormattedNames<TestEnum>();
    }

यह "कुछ 1", "कुछ 2" की वापसी होगी


1
यदि विवरण स्थिर हैं तो ही अच्छा है ... यदि आपके विवरण को उदाहरण के आधार पर बदलने की आवश्यकता है तो यह दृष्टिकोण काम नहीं करेगा।
लेले जूल

3

फ़ॉरच लूप का उपयोग करने के बारे में क्या, शायद आप इसके साथ काम कर सकते हैं?

  int i = 0;
  foreach (var o in values)
  {
    print(names[i], o);
    i++;
  }

शायद ऐसा ही कुछ?


मेरे पास इसके बारे में थाह है ... लेकिन मुझे 'सिंक' में दोनों नामों और मूल्यों तक पहुंचने की आवश्यकता है ... कहते हैं कि नामों [2] को मूल्यों के साथ जोड़ा जाता है [2] और मैं इसे प्राप्त करने के तरीके के बारे में अनिश्चित हूं एक फॉरेस्ट लूप!
टी.के.

मैंने एक उदाहरण जोड़ा है - देखें कि क्या मदद करता है।
ट्विथिथसुगर

3

पुराना प्रश्न है, लेकिन LINQ का उपयोग करते हुए थोड़ा क्लीनर दृष्टिकोण .Cast<>()

var values = Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>();

foreach(var val in values)
{
    Console.WriteLine("Member: {0}",val.ToString());     
}

2

Array में एक GetValue (Int32) विधि है जिसका उपयोग आप किसी निर्दिष्ट इंडेक्स पर मान प्राप्त करने के लिए कर सकते हैं।

Array.GetValue


2

आप स्वरूपण स्ट्रिंग्स का उपयोग करके इसे सरल बना सकते हैं। मैं उपयोग संदेशों में निम्नलिखित स्निपेट का उपयोग करता हूं:

writer.WriteLine("Exit codes are a combination of the following:");
foreach (ExitCodes value in Enum.GetValues(typeof(ExitCodes)))
{
    writer.WriteLine("   {0,4:D}: {0:G}", value);
}

डी प्रारूप निर्दिष्ट करता है एक दशमलव के रूप में एनम मान को प्रारूपित करता है। एक एक्स स्पेसियर भी है जो हेक्साडेसिमल आउटपुट देता है।

जी स्पेसियर एक स्ट्रिंग के रूप में एक एनम का प्रारूपण करता है। यदि झंडे की विशेषता को एनम पर लागू किया जाता है, तो संयुक्त मूल्यों का समर्थन किया जाता है। एक एफ स्पेसर है जो फ़्लैग की तरह हमेशा मौजूद रहता है।

Enum.Format () देखें।


2

Enum.GetValues ​​परिणामों में, इंट के लिए संख्यात्मक मान उत्पन्न करता है। ToString () का उपयोग करके दोस्ताना नाम का उत्पादन होता है। Enum.GetName को कोई अन्य कॉल की आवश्यकता नहीं है।

public enum MyEnum
{
    FirstWord,
    SecondWord,
    Another = 5
};

// later in some method  

 StringBuilder sb = new StringBuilder();
 foreach (var val in Enum.GetValues(typeof(MyEnum))) {
   int numberValue = (int)val;
   string friendyName = val.ToString();
   sb.Append("Enum number " + numberValue + " has the name " + friendyName + "\n");
 }
 File.WriteAllText(@"C:\temp\myfile.txt", sb.ToString());

 // Produces the output file contents:
 /*
 Enum number 0 has the name FirstWord
 Enum number 1 has the name SecondWord
 Enum number 5 has the name Another
 */

0

यहाँ आपके कस्टम Enum ऑब्जेक्ट के माध्यम से पुनरावृति करने का एक सरल तरीका है

For Each enumValue As Integer In [Enum].GetValues(GetType(MyEnum))

     Print([Enum].GetName(GetType(MyEnum), enumValue).ToString)

Next

1
मुझे लगता है कि ओपी ने सी # के लिए कहा।
जेएम।

0

प्राचीन प्रश्न, लेकिन 3Dave के उत्तर ने सबसे आसान दृष्टिकोण प्रदान किया। डीबगिंग के लिए डेटाबेस में एक एनम मान को डीकोड करने के लिए एक एसक्यूएल स्क्रिप्ट उत्पन्न करने के लिए मुझे थोड़ी सहायक विधि की आवश्यकता थी। यह बहुत अच्छा काम किया:

    public static string EnumToCheater<T>() {
        var sql = "";
        foreach (var enumValue in Enum.GetValues(typeof(T)))
            sql += $@"when {(int) enumValue} then '{enumValue}' ";
        return $@"case ?? {sql}else '??' end,";
    }

मेरे पास एक स्थिर विधि है, इसलिए उपयोग है:

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