c# - सी#में enum करने के लिए int कास्ट




enums casting (18)

संख्यात्मक मूल्यों के लिए, यह सुरक्षित है क्योंकि यह किसी ऑब्जेक्ट को वापस करेगा चाहे इससे कोई फर्क नहीं पड़ता:

public static class EnumEx
{
    static public bool TryConvert<T>(int value, out T result)
    {
        result = default(T);
        bool success = Enum.IsDefined(typeof(T), value);
        if (success)
        {
            result = (T)Enum.ToObject(typeof(T), value);
        }
        return success;
    }
}

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


यह उपरोक्त तवानी की उपयोगिता कक्षा जैसे जेनरिकों का उपयोग करते हुए dot.NET 4.0 में आंशिक मिलान के साथ एक लक्ष्य enum के लिए पूर्णांक या स्ट्रिंग को पार करता है। मैं इसे कमांड लाइन स्विच वैरिएबल को कन्वर्ट करने के लिए उपयोग कर रहा हूं जो अपूर्ण हो सकता है। चूंकि एक enum शून्य नहीं हो सकता है, आपको तार्किक रूप से एक डिफ़ॉल्ट मान प्रदान करना चाहिए। इसे इस तरह कहा जा सकता है:

var result = EnumParser<MyEnum>.Parse(valueToParse, MyEnum.FirstValue);

यहां कोड है:

using System;

public class EnumParser<T> where T : struct
{
    public static T Parse(int toParse, T defaultVal)
    {
        return Parse(toParse + "", defaultVal);
    }
    public static T Parse(string toParse, T defaultVal) 
    {
        T enumVal = defaultVal;
        if (defaultVal is Enum && !String.IsNullOrEmpty(toParse))
        {
            int index;
            if (int.TryParse(toParse, out index))
            {
                Enum.TryParse(index + "", out enumVal);
            }
            else
            {
                if (!Enum.TryParse<T>(toParse + "", true, out enumVal))
                {
                    MatchPartialName(toParse, ref enumVal);
                }
            }
        }
        return enumVal;
    }

    public static void MatchPartialName(string toParse, ref T enumVal)
    {
        foreach (string member in enumVal.GetType().GetEnumNames())
        {
            if (member.ToLower().Contains(toParse.ToLower()))
            {
                if (Enum.TryParse<T>(member + "", out enumVal))
                {
                    break;
                }
            }
        }
    }
}

एफवाईआई: प्रश्न पूर्णांक के बारे में था, जिसका कोई भी उल्लेख नहीं किया गया है, यह भी Enum.TryParse () में स्पष्ट रूप से परिवर्तित होगा


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

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

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

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


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

MyEnum e = (MyEnum)3;

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

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

मेरे मामले में, मुझे डब्ल्यूसीएफ सेवा से enum वापस करने की जरूरत है। मुझे एक दोस्ताना नाम भी चाहिए, न कि enum.ToString ()।

यहां मेरी डब्ल्यूसीएफ कक्षा है।

[DataContract]
public class EnumMember
{
    [DataMember]
    public string Description { get; set; }

    [DataMember]
    public int Value { get; set; }

    public static List<EnumMember> ConvertToList<T>()
    {
        Type type = typeof(T);

        if (!type.IsEnum)
        {
            throw new ArgumentException("T must be of type enumeration.");
        }

        var members = new List<EnumMember>();

        foreach (string item in System.Enum.GetNames(type))
        {
            var enumType = System.Enum.Parse(type, item);

            members.Add(
                new EnumMember() { Description = enumType.GetDescriptionValue(), Value = ((IConvertible)enumType).ToInt32(null) });
        }

        return members;
    }
}

यहां एक्सटेंशन विधि है जो Enum से विवरण प्राप्त करती है।

    public static string GetDescriptionValue<T>(this T source)
    {
        FieldInfo fileInfo = source.GetType().GetField(source.ToString());
        DescriptionAttribute[] attributes = (DescriptionAttribute[])fileInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);            

        if (attributes != null && attributes.Length > 0)
        {
            return attributes[0].Description;
        }
        else
        {
            return source.ToString();
        }
    }

कार्यान्वयन:

return EnumMember.ConvertToList<YourType>();

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

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

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

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

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

नीचे Enums के लिए एक अच्छी उपयोगिता वर्ग है

public static class EnumHelper
{
    public static int[] ToIntArray<T>(T[] value)
    {
        int[] result = new int[value.Length];
        for (int i = 0; i < value.Length; i++)
            result[i] = Convert.ToInt32(value[i]);
        return result;
    }

    public static T[] FromIntArray<T>(int[] value) 
    {
        T[] result = new T[value.Length];
        for (int i = 0; i < value.Length; i++)
            result[i] = (T)Enum.ToObject(typeof(T),value[i]);
        return result;
    }


    internal static T Parse<T>(string value, T defaultValue)
    {
        if (Enum.IsDefined(typeof(T), value))
            return (T) Enum.Parse(typeof (T), value);

        int num;
        if(int.TryParse(value,out num))
        {
            if (Enum.IsDefined(typeof(T), num))
                return (T)Enum.ToObject(typeof(T), num);
        }

        return defaultValue;
    }
}

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

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

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


वैकल्पिक रूप से, एक-लाइनर के बजाय एक एक्सटेंशन विधि का उपयोग करें:

public static T ToEnum<T>(this string enumString)
{
    return (T) Enum.Parse(typeof (T), enumString);
}

उपयोग:

Color colorEnum = "Red".ToEnum<Color>();

या

string color = "Red";
var colorEnum = color.ToEnum<Color>();

थोड़ा सा मूल प्रश्न से दूर हो रहा है, लेकिन मुझे स्टैक ओवरफ़्लो प्रश्न का उत्तर मिला, एनम उपयोगी से int मान प्राप्त करेंpublic const int गुणों के साथ एक स्थैतिक वर्ग बनाएं, जिससे आप आसानी से संबंधित int स्थिरांक का एक समूह एकत्र कर सकें, और फिर उन्हें उपयोग करते समय उन्हें int डालना न पड़े।

public static class Question
{
    public static readonly int Role = 2;
    public static readonly int ProjectFunding = 3;
    public static readonly int TotalEmployee = 4;
    public static readonly int NumberOfServers = 5;
    public static readonly int TopBusinessConcern = 6;
}

जाहिर है, कुछ enum प्रकार की कार्यक्षमता खो जाएगी, लेकिन डेटाबेस आईडी स्थिरांक का एक गुच्छा भंडारण के लिए, यह एक सुंदर साफ समाधान की तरह लगता है।


Enum से और उसके लिए डालने के विभिन्न तरीके

enum orientation : byte
{
 north = 1,
 south = 2,
 east = 3,
 west = 4
}

class Program
{
  static void Main(string[] args)
  {
    orientation myDirection = orientation.north;
    Console.WriteLine(“myDirection = {0}”, myDirection); //output myDirection =north
    Console.WriteLine((byte)myDirection); //output 1

    string strDir = Convert.ToString(myDirection);
        Console.WriteLine(strDir); //output north

    string myString = “north”; //to convert string to Enum
    myDirection = (orientation)Enum.Parse(typeof(orientation),myString);


 }
}

निम्नलिखित उदाहरण लें:

int one = 1;
MyEnum e = (MyEnum)one;

यह आपको किसी वांछित डेटा को उपयोगकर्ता वांछित enum में कनवर्ट करने में मदद कर सकता है। मान लें कि आपके पास नीचे की तरह एक enum है जो डिफ़ॉल्ट int द्वारा। कृपया अपने enum के पहले एक डिफ़ॉल्ट मान जोड़ें। इनपुट इनपुट के साथ कोई मिलान नहीं होने पर हेल्पर्स मेडथोड पर इसका उपयोग किया जाता है।

public enum FriendType  
{
    Default,
    Audio,
    Video,
    Image
}

public static class EnumHelper<T>
{
    public static T ConvertToEnum(dynamic value)
    {
        var result = default(T);
        var tempType = 0;

        //see Note below
        if (value != null &&
            int.TryParse(value.ToString(), out  tempType) && 
            Enum.IsDefined(typeof(T), tempType))
        {
            result = (T)Enum.ToObject(typeof(T), tempType); 
        }
        return result;
    }
}

एनबी: यहां मैं int में मूल्य को पार्स करने का प्रयास करता हूं, क्योंकि enum डिफ़ॉल्ट int से है यदि आप इस तरह के enum को परिभाषित करते हैं जो बाइट प्रकार है।

public enum MediaType : byte
{
    Default,
    Audio,
    Video,
    Image
} 

आपको सहायक विधि पर पार्सिंग बदलने की जरूरत है

int.TryParse(value.ToString(), out  tempType)

सेवा मेरे

byte.TryParse(value.ToString(), out tempType)

मैं इनपुट का पालन करने के लिए अपनी विधि की जांच

EnumHelper<FriendType>.ConvertToEnum(null);
EnumHelper<FriendType>.ConvertToEnum("");
EnumHelper<FriendType>.ConvertToEnum("-1");
EnumHelper<FriendType>.ConvertToEnum("6");
EnumHelper<FriendType>.ConvertToEnum("");
EnumHelper<FriendType>.ConvertToEnum("2");
EnumHelper<FriendType>.ConvertToEnum(-1);
EnumHelper<FriendType>.ConvertToEnum(0);
EnumHelper<FriendType>.ConvertToEnum(1);
EnumHelper<FriendType>.ConvertToEnum(9);

मेरी अंग्रेजी के लिए खेद है


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

enum Importance
{}

Importance importance;

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

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

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

पिछले उत्तरों में जोड़ने के लिए, और नल और एनपीई के आसपास कुछ चर्चाओं को संबोधित करने के लिए मैं अनुपस्थित / अमान्य मामलों को संभालने के लिए गुवा विकल्प का उपयोग कर रहा हूं। यह यूआरआई / पैरामीटर पार्सिंग के लिए बहुत अच्छा काम करता है।

public enum E {
    A,B,C;
    public static Optional<E> fromString(String s) {
        try {
            return Optional.of(E.valueOf(s.toUpperCase()));
        } catch (IllegalArgumentException|NullPointerException e) {
            return Optional.absent();
        }
    }
}

उन लोगों के लिए जिन्हें पता नहीं है, वैकल्पिक के साथ शून्य से बचने के बारे में कुछ और जानकारी यहां दी गई है: https://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained#Optional





c# enums casting