[c#] सी # में enum को कास्ट करें



Answers

बस इसे कास्ट करें:

MyEnum e = (MyEnum)3;

आप जांच सकते हैं कि यह Enum.IsDefined का उपयोग कर सीमा में है Enum.IsDefined :

if (Enum.IsDefined(typeof(MyEnum), 3)) { ... }
Question

सी # में एक enum लिए एक int कैसे डाला जा सकता है?




यह एक झंडे की गणना जागरूक सुरक्षित कनवर्ट विधि है:

public static bool TryConvertToEnum<T>(this int instance, out T result)
  where T: struct
{
  var enumType = typeof (T);
  if (!enumType.IsEnum)
  {
    throw new ArgumentException("The generic type must be an enum.");
  }
  var success = Enum.IsDefined(enumType, instance);
  if (success)
  {
    result = (T)Enum.ToObject(enumType, instance);
  }
  else
  {
    result = default(T);
  }
  return success;
}



एक स्ट्रिंग से: (Enum.Parse तिथि से बाहर है, Enum.TryParse का उपयोग करें)

enum Importance
{}

Importance importance;

if (Enum.TryParse(value, out importance))
{
}



यदि आप 4.0 .NET Framework के लिए तैयार हैं, तो एक नया Enum.TryParse () फ़ंक्शन है जो बहुत उपयोगी है और [ध्वज] विशेषता के साथ अच्छी तरह से खेलता है। Enum.TryParse विधि देखें (स्ट्रिंग, TENum%)




एक स्ट्रिंग को ENUM या int से ENUM स्थिर में बदलने के लिए हमें Enum.Parse फ़ंक्शन का उपयोग करने की आवश्यकता है। यहां एक यूट्यूब वीडियो https://www.youtube.com/watch?v=4nhx4VwdRDk जो वास्तव में स्ट्रिंग के साथ प्रदर्शित करता है और यह int के लिए भी लागू होता है।

कोड नीचे दिखाया गया है जहां "लाल" स्ट्रिंग है और "MyColors" रंग ENUM है जिसमें रंग स्थिरांक है।

MyColors EnumColors = (MyColors)Enum.Parse(typeof(MyColors), "Red");



मुझे पूरा जवाब मिलना है, लोगों को यह जानना है कि एनईटी में आंतरिक रूप से कैसे काम करता है।

कितना रद्दी निर्माण कार्य है

.NET में एक enum एक संरचना है जो मानों (फ़ील्ड) के सेट को मूल प्रकार (डिफ़ॉल्ट int ) पर मैप करती है। हालांकि, आप वास्तव में अभिन्न प्रकार का चयन कर सकते हैं जो आपके enum मानचित्र को:

public enum Foo : short

इस मामले में enum को short डेटा प्रकार में मैप किया जाता है, जिसका अर्थ यह है कि इसे स्मृति में एक छोटा सा रूप में संग्रहीत किया जाएगा और जब आप इसे कास्ट करेंगे और इसका उपयोग करेंगे तो उतना ही व्यवहार करेंगे।

यदि आप इसे आईएल पॉइंट व्यू से देखते हैं, तो एक (सामान्य, int) enum इस तरह दिखता है:

.class public auto ansi serializable sealed BarFlag extends System.Enum
{
    .custom instance void System.FlagsAttribute::.ctor()
    .custom instance void ComVisibleAttribute::.ctor(bool) = { bool(true) }

    .field public static literal valuetype BarFlag AllFlags = int32(0x3fff)
    .field public static literal valuetype BarFlag Foo1 = int32(1)
    .field public static literal valuetype BarFlag Foo2 = int32(0x2000)

    // and so on for all flags or enum values

    .field public specialname rtspecialname int32 value__
}

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

इस बिंदु पर मैं उस System.Enum को इंगित करना चाहता हूं। BarFlag एक वैल्यू टाइप है, जिसका मूल रूप से मतलब है कि BarFlag मेमोरी में 4 बाइट लेगा और Foo 2 ले जाएगा - उदाहरण के लिए अंतर्निहित प्रकार का आकार (यह वास्तव में और अधिक है उससे जटिल, लेकिन हे ...)।

उत्तर

इसलिए, यदि आपके पास एक पूर्णांक है जिसे आप एक enum पर मैप करना चाहते हैं, तो रनटाइम को केवल 2 चीजें करना पड़ता है: 4 बाइट्स कॉपी करें और इसे कुछ और नाम दें (enum का नाम)। प्रतिलिपि निहित है क्योंकि डेटा को मूल्य प्रकार के रूप में संग्रहीत किया जाता है - इसका मूल रूप से अर्थ है कि यदि आप अप्रबंधित कोड का उपयोग करते हैं, तो आप डेटा कॉपी किए बिना बस enums और integers का आदान-प्रदान कर सकते हैं।

इसे सुरक्षित बनाने के लिए, मुझे लगता है कि यह जानने का सबसे अच्छा अभ्यास है कि अंतर्निहित प्रकार समान या निहित रूप से परिवर्तनीय हैं और यह सुनिश्चित करने के लिए कि enum मान मौजूद हैं (वे डिफ़ॉल्ट रूप से चेक नहीं किए जाते हैं!)।

यह कैसे काम करता है यह देखने के लिए, निम्न कोड आज़माएं:

public enum MyEnum : int
{
    Foo = 1,
    Bar = 2,
    Mek = 5
}

static void Main(string[] args)
{
    var e1 = (MyEnum)5;
    var e2 = (MyEnum)6;

    Console.WriteLine("{0} {1}", e1, e2);
    Console.ReadLine();
}

ध्यान दें कि e2 को कास्टिंग भी काम करता है! इसके ऊपर संकलक परिप्रेक्ष्य से यह समझ में आता है: value__ फ़ील्ड बस 5 या 6 से भरा हुआ है और जब Console.WriteLine ToString() कॉल करता है, e1 का नाम हल हो जाता है जबकि e2 का नाम नहीं होता है।

यदि यह आपके इरादे से नहीं है, तो Enum.IsDefined(typeof(MyEnum), 6) का उपयोग यह जांचने के लिए करें कि क्या आप परिभाषित enum पर नक्शे कास्टिंग कर रहे हैं।

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

public enum MyEnum : short
{
    Mek = 5
}

static void Main(string[] args)
{
    var e1 = (MyEnum)32769; // will not compile, out of bounds for a short

    object o = 5;
    var e2 = (MyEnum)o;     // will throw at runtime, because o is of type int

    Console.WriteLine("{0} {1}", e1, e2);
    Console.ReadLine();
}



यदि आपके पास एक पूर्णांक है जो बिटमैस्क के रूप में कार्य करता है और [ध्वज] गणना में एक या अधिक मानों का प्रतिनिधित्व कर सकता है, तो आप व्यक्तिगत ध्वज मानों को एक सूची में पार्स करने के लिए इस कोड का उपयोग कर सकते हैं:

for (var flagIterator = 0x1; flagIterator <= 0x80000000; flagIterator <<= 1)
{
    // Check to see if the current flag exists in the bit mask
    if ((intValue & flagIterator) != 0)
    {
        // If the current flag exists in the enumeration, then we can add that value to the list
        // if the enumeration has that flag defined
        if (Enum.IsDefined(typeof(MyEnum), flagIterator))
            ListOfEnumValues.Add((MyEnum)flagIterator);
    }
}



निम्नलिखित थोड़ा बेहतर विस्तार विधि है

public static string ToEnumString<TEnum>(this int enumValue)
        {
            var enumString = enumValue.ToString();
            if (Enum.IsDefined(typeof(TEnum), enumValue))
            {
                enumString = ((TEnum) Enum.ToObject(typeof (TEnum), enumValue)).ToString();
            }
            return enumString;
        }



मैं अब और नहीं जानता जहां मुझे इस एनम एक्सटेंशन का हिस्सा मिलता है, लेकिन यह स्टैक ओवरफ्लो से है। मुझे इसके लिए खेद है! लेकिन मैंने इसे लिया और इसे ध्वज के साथ enums के लिए संशोधित किया। झंडे के साथ enums के लिए मैंने यह किया:

  public static class Enum<T> where T : struct
  {
     private static readonly IEnumerable<T> All = Enum.GetValues(typeof (T)).Cast<T>();
     private static readonly Dictionary<int, T> Values = All.ToDictionary(k => Convert.ToInt32(k));

     public static T? CastOrNull(int value)
     {
        T foundValue;
        if (Values.TryGetValue(value, out foundValue))
        {
           return foundValue;
        }

        // For enums with Flags-Attribut.
        try
        {
           bool isFlag = typeof(T).GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0;
           if (isFlag)
           {
              int existingIntValue = 0;

              foreach (T t in Enum.GetValues(typeof(T)))
              {
                 if ((value & Convert.ToInt32(t)) > 0)
                 {
                    existingIntValue |= Convert.ToInt32(t);
                 }
              }
              if (existingIntValue == 0)
              {
                 return null;
              }

              return (T)(Enum.Parse(typeof(T), existingIntValue.ToString(), true));
           }
        }
        catch (Exception)
        {
           return null;
        }
        return null;
     }
  }

उदाहरण:

[Flags]
public enum PetType
{
  None = 0, Dog = 1, Cat = 2, Fish = 4, Bird = 8, Reptile = 16, Other = 32
};

integer values 
1=Dog;
13= Dog | Fish | Bird;
96= Other;
128= Null;



मैं अपने enum में int डालने के लिए कोड के इस टुकड़े का उपयोग कर रहा हूँ:

if (typeof(YourEnum).IsEnumDefined(valueToCast)) return (YourEnum)valueToCast;
else { //handle it here, if its not defined }

मुझे यह सबसे अच्छा समाधान मिल रहा है।




Related