c# - सी#में enum से int मूल्य प्राप्त करें




enums casting (16)

मेरे पास Questions (बहुवचन) नामक एक वर्ग है। इस वर्ग में Question (एकवचन) नामक एक enum है जो इस तरह दिखता है।

public enum Question
{
    Role = 2,
    ProjectFunding = 3,
    TotalEmployee = 4,
    NumberOfServers = 5,
    TopBusinessConcern = 6
}

Questions वर्ग में, मेरे पास एक get(int foo) फ़ंक्शन है जो उस foo लिए एक Questions ऑब्जेक्ट देता है। क्या enum से पूर्णांक मान प्राप्त करने का कोई आसान तरीका है, इसलिए मैं Questions.Get(Question.Role) जैसे कुछ कर सकता हूं। Get Questions.Get(Question.Role) ?


Enum को int में बदलने के बजाय इसे आज़माएं:

public static class ReturnType
{
    public static readonly int Success = 1;
    public static readonly int Duplicate = 2;
    public static readonly int Error = -1;        
}

Int या छोटे enums के साथ मेरा एफएवी हैक:

GetHashCode();

एक enum के लिए

public enum Test
{
    Min = Int32.MinValue,
    One = 1,
    Max = Int32.MaxValue,
}

इस

var values = Enum.GetValues(typeof(Test));

foreach (var val in values) 
{
    Console.WriteLine(val.GetHashCode());
    Console.WriteLine(((int)val));
    Console.WriteLine(val);
}

आउटपुट

one
1
1  
max
2147483647
2147483647    
min
-2147483648
-2147483648    

अस्वीकरण: लंबे समय के आधार पर enums के लिए काम नहीं करता है


इसके बजाय एक विस्तार विधि के बारे में:

public static class ExtensionMethods
{
    public static int IntValue(this Enum argEnum)
    {
        return Convert.ToInt32(argEnum);
    }
}

और उपयोग थोड़ा सुंदर है:

var intValue = Question.Role.IntValue();

इसे इस्तेमाल करे :

int value = YourEnum.ToString("D");

उदाहरण मैं सुझाव देना चाहता हूं कि 'एन' से 'int' मान प्राप्त करें, '

public enum Sample
{Book =1, Pen=2, Pencil =3}

int answer = (int)Sample.Book;

अब जवाब 1 होगा।

मुझे उम्मीद है कि यह किसी की मदद कर सकता है।


उदाहरण:

Public Enum EmpNo
{
    Raj = 1
    Rahul,
    Priyanka
}

और enum मान प्राप्त करने के लिए पीछे कोड में:

int setempNo = (int)EmpNo.Raj; //This will give setempNo = 1

या

int setempNo = (int)EmpNo.Rahul; //This will give setempNo = 2

Enums 1 से बढ़ेगा, और आप प्रारंभ मूल्य सेट कर सकते हैं। अन्यथा इसे शुरुआत में 0 के रूप में असाइन किया जाएगा।


चूंकि enums को कई आदिम प्रकारों के साथ घोषित किया जा सकता है, इसलिए किसी भी enum प्रकार को कास्ट करने के लिए एक सामान्य विस्तार विधि उपयोगी हो सकती है।

        enum Box
        {
            HEIGHT,
            WIDTH,
            DEPTH
        }

        public static void UseEnum()
        {
            int height = Box.HEIGHT.GetEnumValue<int>();
            int width = Box.WIDTH.GetEnumValue<int>();
            int depth = Box.DEPTH.GetEnumValue<int>();
        }

        public static T GetEnumValue<T>(this object e) => (T)e;

चूंकि एनम्स किसी भी अभिन्न प्रकार ( byte , int , short इत्यादि) हो सकते हैं, इसलिए GetTypeCode के अंतर्निहित अभिन्न मूल्य को प्राप्त करने का एक और अधिक मजबूत तरीका Convert क्लास के साथ GetTypeCode विधि का उपयोग करना होगा:

enum Sides {
    Left, Right, Top, Bottom
}
Sides side = Sides.Bottom;

object val = Convert.ChangeType(side, side.GetTypeCode());
Console.WriteLine(val);

यह अंतर्निहित अभिन्न प्रकार के बावजूद काम करना चाहिए।


मैंने हाल ही में संरक्षित रचनाकारों और पूर्वनिर्धारित स्थैतिक उदाहरणों के साथ कक्षाओं का उपयोग करने के पक्ष में अपने कोड में enums का उपयोग करने से दूर कर दिया है ( Roelof - C # के लिए धन्यवाद मान्य एनम मूल्य - भविष्यरोधक विधि )।

इसके प्रकाश में, नीचे मैं इस मुद्दे से कैसे संपर्क करूंगा (अंतर्निहित रूपांतरण / int )।

public class Question
{
    // Attributes
    protected int index;
    protected string name;
    // Go with a dictionary to enforce unique index
    //protected static readonly ICollection<Question> values = new Collection<Question>();
    protected static readonly IDictionary<int,Question> values = new Dictionary<int,Question>();

    // Define the "enum" values
    public static readonly Question Role = new Question(2,"Role");
    public static readonly Question ProjectFunding = new Question(3, "Project Funding");
    public static readonly Question TotalEmployee = new Question(4, "Total Employee");
    public static readonly Question NumberOfServers = new Question(5, "Number of Servers");
    public static readonly Question TopBusinessConcern = new Question(6, "Top Business Concern");

    // Constructors
    protected Question(int index, string name)
    {
        this.index = index;
        this.name = name;
        values.Add(index, this);
    }

    // Easy int conversion
    public static implicit operator int(Question question) =>
        question.index; //nb: if question is null this will return a null pointer exception

    public static implicit operator Question(int index) =>        
        values.TryGetValue(index, out var question) ? question : null;

    // Easy string conversion (also update ToString for the same effect)
    public override string ToString() =>
        this.name;

    public static implicit operator string(Question question) =>
        question?.ToString();

    public static implicit operator Question(string name) =>
        name == null ? null : values.Values.FirstOrDefault(item => name.Equals(item.name, StringComparison.CurrentCultureIgnoreCase));


    // If you specifically want a Get(int x) function (though not required given the implicit converstion)
    public Question Get(int foo) =>
        foo; //(implicit conversion will take care of the conversion for you)
}

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

एनबी: सी # 6 सुविधाओं का उपयोग करने के लिए उत्तर 2018-04-27 अपडेट किया गया; यानी घोषणा अभिव्यक्ति और लैम्ब्डा अभिव्यक्ति शरीर परिभाषाएं। मूल कोड के लिए संशोधन इतिहास देखें। इस परिभाषा को थोड़ा कम वर्बोज़ बनाने का लाभ है; जो इस उत्तर के दृष्टिकोण के बारे में मुख्य शिकायतों में से एक रहा था।


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

enum Talen
{
    Engels = 1, Italiaans = 2, Portugees = 3, Nederlands = 4, Duits = 5, Dens = 6
}

Talen Geselecteerd;    

public void Form1()
{
    InitializeComponent()
    Geselecteerd = Talen.Nederlands;
}

// You can use the Enum type as a parameter, so any enumeration from any enumerator can be used as parameter
void VeranderenTitel(Enum e)
{
    this.Text = Convert.ToInt32(e).ToString();
}

यह विंडो शीर्षक को 4 में बदल देगा क्योंकि परिवर्तनीय Geselecteerd Talen.Nederlands । अगर मैं इसे Talen.Portugees और विधि को फिर से कॉल करता Talen.Portugees , तो टेक्स्ट 3 में बदल जाएगा।

मुझे इंटरनेट पर इस सरल समाधान को खोजने में कठिनाई हुई और मुझे यह नहीं मिला, इसलिए मैं कुछ परीक्षण कर रहा था और इसे पाया। उम्मीद है की यह मदद करेगा। ;)


यह सुनिश्चित करने के लिए कि enum value मौजूद है और फिर इसे पार्स करें, आप निम्न कार्य भी कर सकते हैं।

// Fake Day of Week
string strDOWFake = "SuperDay";
// Real Day of Week
string strDOWReal = "Friday";
// Will hold which ever is the real DOW.
DayOfWeek enmDOW;

// See if fake DOW is defined in the DayOfWeek enumeration.
if (Enum.IsDefined(typeof(DayOfWeek), strDOWFake))
{
// This will never be reached since "SuperDay" 
// doesn't exist in the DayOfWeek enumeration.
    enmDOW = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), strDOWFake);
}
// See if real DOW is defined in the DayOfWeek enumeration.
else if (Enum.IsDefined(typeof(DayOfWeek), strDOWReal))
{
    // This will parse the string into it's corresponding DOW enum object.
    enmDOW = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), strDOWReal);
}

// Can now use the DOW enum object.
Console.Write("Today is " + enmDOW.ToString() + ".");

आशा है कि ये आपकी मदद करेगा।


विस्तार विधि निम्नलिखित है

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

शायद मैंने इसे याद किया लेकिन किसी ने भी एक साधारण सामान्य विस्तार विधि की कोशिश की है। यह मेरे लिए बहुत अच्छा काम करता है। आप इस प्रकार अपने एपीआई में टाइप कास्ट से बच सकते हैं लेकिन आखिरकार इसके परिणामस्वरूप एक परिवर्तन प्रकार का ऑपरेशन होता है। Roselyn प्रोग्रामिंग के लिए यह एक अच्छा मामला है कि कंपाइलर आपके लिए GetValue विधि बनाये।

    public static void Main()
    {
        int test = MyCSharpWrapperMethod(TestEnum.Test1);

        Debug.Assert(test == 1);
    }

    public static int MyCSharpWrapperMethod(TestEnum customFlag)
    {
        return MyCPlusPlusMethod(customFlag.GetValue<int>());
    }

    public static int MyCPlusPlusMethod(int customFlag)
    {
        //Pretend you made a PInvoke or COM+ call to C++ method that require an integer
        return customFlag;
    }

    public enum TestEnum
    {
        Test1 = 1,
        Test2 = 2,
        Test3 = 3
    }
}

public static class EnumExtensions
{
    public static T GetValue<T>(this Enum enumeration)
    {
        T result = default(T);

        try
        {
            result = (T)Convert.ChangeType(enumeration, typeof(T));
        }
        catch (Exception ex)
        {
            Debug.Assert(false);
            Debug.WriteLine(ex);
        }

        return result;
    }
}    

संबंधित नोट पर, यदि आप System.Enum से int मान प्राप्त करना चाहते हैं, तो यहां दिया गया है:

Enum e = Question.Role;

आप उपयोग कर सकते हैं:

int i = Convert.ToInt32(e);
int i = (int)(object)e;
int i = (int)Enum.Parse(e.GetType(), e.ToString());
int i = (int)Enum.ToObject(e.GetType(), e);

आखिरी दो सादे बदसूरत हैं। मैं पहले को पसंद करता हूं।


Question question = Question.Role;
int value = (int) question;

परिणामस्वरूप value == 2


int number = Question.Role.GetHashCode();

number मूल्य 2 होना चाहिए।







int