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




13 Answers

यह मुझे लगता है कि आप वास्तव में मूल्यों के बजाय प्रत्येक 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)) उपयोग 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());
    }
}
c# .net enums enumeration

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

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

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

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

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

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

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




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

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




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

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

वहां आप IEnumerable<Suit>




बस मेरा समाधान जोड़ने के लिए, जो कॉम्पैक्ट फ्रेमवर्क (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>();



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



तीन तरीके से:

1. Enum.GetValues(type) //since .NET 1.1, not in silverlight or compact framewok
2. type.GetEnumValues() //only on .NET 4 and above
3. type.GetFields().Where(x => x.IsLiteral).Select(x => x.GetValue(null)) //works everywhere

निश्चित नहीं है कि 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)));
    }
}



मैं 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);
}



मुझे राय नहीं है कि यह बेहतर है, या यहां तक ​​कि अच्छा है, बस एक और समाधान बता रहा है।

यदि enum मान 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;
    }
}

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




यहां एक डीडीएल के लिए चयन विकल्प बनाने का एक कामकाजी उदाहरण है

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



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

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

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



एक enum को बदलने के लिए एक सरल और सामान्य तरीका आप बातचीत कर सकते हैं:

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



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

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

कॉल करें और अपने enum पास, अब आप foreach का उपयोग कर इसके माध्यम से फिर से कर सकते हैं

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



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

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

System.Enum.GetNames विधि का उपयोग स्ट्रिंग्स की सरणी को पुनर्प्राप्त करने के लिए किया जा सकता है जो नाम मानों के नाम हैं, जैसा कि नाम बताता है।

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




Related