सवाल स्ट्रिंग के रूप में सी # संख्यात्मक enum मान


मेरे पास निम्नलिखित enum है:

public enum Urgency {
    VeryHigh = 1,
    High     = 2,
    Routine  = 4
}

मैं एक ला सकता हूँ स्ट्रिंग के रूप में enum "मान" इस तरह:

((int)Urgency.Routine).ToString() // returns "4"  

नोट: यह इससे अलग है:

Urgency.Routine.ToString() // returns "Routine"
(int)Urgency.Routine       // returns 4

क्या कोई तरीका है कि मैं एक विस्तार वर्ग, या एक स्थिर उपयोगिता वर्ग बना सकता हूं, जो कुछ वाक्य रचनात्मक चीनी प्रदान करेगा? :)


44
2017-08-09 22:33


मूल


क्या आप जो खोज रहे हैं उसके बारे में अधिक सटीक हो सकते हैं? - Kirk Woll
i.e. enumValue.ToValueString () == int मान? - Kirk Woll
अंतर्निहित int मान - लेकिन एक स्ट्रिंग के रूप में (एक स्ट्रिंग के रूप में enum नहीं) एक int और फिर एक स्ट्रिंग के लिए कास्टिंग के पुरातन वाक्यविन्यास को याद करने के बजाय, एक विधि के साथ एक स्थिर वर्ग कोई एनम वैल्यू का उपयोग करना आसान हो जाएगा। मुझे संदेह है कि भाषा का समर्थन नहीं हो सकता है जो मैं कर रहा हूं। - David Moorhouse
.. सोचो मैंने जो किया वह मैंने किया था। - spender


जवाब:


आपको केवल प्रारूप स्ट्रिंग देने के लिए Enums ToString विधि के ओवरलोड का उपयोग करने में सक्षम होना चाहिए, यह enum के मान को स्ट्रिंग के रूप में प्रिंट करेगा।

public static class Program
{
    static void Main(string[] args)
    {
        var val = Urgency.High;
        Console.WriteLine(val.ToString("D")); 
    }
}

public enum Urgency 
{ 
    VeryHigh = 1,
    High = 2,
    Low = 4
}

84
2017-08-09 23:23



बकवास। सुंदर सादगी। मुझे अपना जवाब हटाना चाहता है! +1 - spender
हां, क्वेरी के एक अलग दृष्टिकोण के साथ एक ही परिणाम प्रदान करने में पार्श्व सोच का अच्छा सा। कोड public static string NumberString(this Enum enVal){return enVal.ToString("D");} यह होना चाहिए कि आपका विचार क्या है और इसे विस्तारित तरीके से बदल दिया गया है। - Jon Hanna
महान सामान ... नीचे मेरा जवाब देखें - David Moorhouse
मैं इसे एक दूसरे से भी पसंद करता हूं जो एक्सटेंशन विधि का उपयोग करता है। विस्तार विधि बनाकर आप बस अपने कोड पर अनावश्यक निर्भरता जोड़ते हैं। कम से कम निर्भरता याद रखें कि आपके पास अपना कोड बेहतर है !! - ktutnik
एकाधिक enum मानों पर लागू करने के लिए (उदाहरण): new[] { ProductStatus.Open, ProductStatus.Deprecated }.Select(s => s.ToString("D")) - EriF89


Enms के लिए अधिक "मानव पठनीय" विवरण प्राप्त करने के लिए (उदा। "उदाहरण के लिए" अति उच्च "के बजाय" बहुत उच्च ") मैंने गुण के साथ enum मानों को सजाया है:

public enum MeasurementType
{
    Each,

    [DisplayText("Lineal Metres")]
    LinealMetre,

    [DisplayText("Square Metres")]
    SquareMetre,

    [DisplayText("Cubic Metres")]
    CubicMetre,

    [DisplayText("Per 1000")]
    Per1000,

    Other
}


public class DisplayText : Attribute
{

    public DisplayText(string Text)
    {
        this.text = Text;
    }


    private string text;


    public string Text
    {
        get { return text; }
        set { text = value; }
    }
}

फिर, इस तरह एक विस्तार विधि का उपयोग किया:

    public static string ToDescription(this Enum en)
    {

        Type type = en.GetType();

        MemberInfo[] memInfo = type.GetMember(en.ToString());

        if (memInfo != null && memInfo.Length > 0)
        {

            object[] attrs = memInfo[0].GetCustomAttributes(
                                          typeof(DisplayText),

                                          false);

            if (attrs != null && attrs.Length > 0)

                return ((DisplayText)attrs[0]).Text;

        }

        return en.ToString();

    }

फिर आप बस कॉल कर सकते हैं

myEnum.ToDescription ()
 अपने enum को अधिक पठनीय पाठ के रूप में प्रदर्शित करने के लिए।


17
2017-08-09 22:54



वाह, यह भी इस समस्या के लिए एक बहुत बीमार समाधान है - Robert Karl
मैंने ऐसा ही किया है, हालांकि अक्सर ऊंट-आवरण के सम्मेलन पर निर्भर करता है। हालांकि सवाल नहीं करता है कि सवाल क्या है। - Jon Hanna
उत्कृष्ट उत्तर, लेकिन सवाल के लिए नहीं पूछा। - Brady Moritz
धन्यवाद - लेकिन int मान वापस नहीं करता - एक स्ट्रिंग के रूप में :) - David Moorhouse
आपने घोषणा की नहीं है DisplayText विशेषता। क्या आप इसे संभवतः जोड़ सकते हैं? - Alex Essilfie


यदि आप इस enum से निपटना चाहते हैं, तो मार्क बायर के समाधान का उपयोग करें।

अधिक सामान्य समाधान के लिए:

public static string NumberString(this Enum enVal) 
{
    return Convert.ToDecimal(enVal).ToString("0");
}

दशमलव में कनवर्ट करने का मतलब है कि आपको 8 अलग-अलग अनुमत अंतर्निहित अभिन्न प्रकारों से स्पष्ट रूप से निपटने की आवश्यकता नहीं है, क्योंकि उनमें से सभी हानिकारक रूप से दशमलव में परिवर्तित होते हैं, लेकिन एक दूसरे के साथ नहीं (उलझन और लंबे समय तक एक-दूसरे के बीच हानि रहित रूप से परिवर्तित नहीं होते हैं, लेकिन दोनों संभाल सकते हैं बाकी सब)। ऐसा करना शायद तेज़ होगा (esp। अगर आप तुलना के अपने क्रम में अच्छी तरह से चुनते हैं), लेकिन अपेक्षाकृत कम लाभ के लिए बहुत अधिक वर्बोज़।

संपादित करें:

उपर्युक्त फ्रैंकेंटोश के रूप में उतना अच्छा नहीं है, फ्रैंकेंटोश ने असली समस्या के सवाल को देखा और इसे बहुत स्पष्ट रूप से हल किया।


4
2017-08-09 23:20





थोड़ा प्रतिबिंब के बारे में कैसे? सभी अंतर्निहित प्रकारों के साथ काम करना चाहिए।

public static class EnumTools
{
    public static string ToRawValueString(this Enum e)
    {
        return e
            .GetType()
            .GetFields(BindingFlags.Public | BindingFlags.Static)
            .First(f => f.Name==e.ToString())
            .GetRawConstantValue()
            .ToString();
    }
}

फिर:

Console.WriteLine(Urgency.High.ToRawValueString()); //Writes "2"

2
2017-08-09 22:56



इसे प्यार करना होगा ... - Robert Karl
पहला () असफल होने जा रहा है यदि मान से मेल खाने वाली गणना में परिभाषित मूल्य नहीं है, विशेष रूप से ध्वज enums के साथ आम है और अन्य मामलों में संभव है (जब भी Enum.IsDefined(e.GetType(), e) झूठा रिटर्न) इस तरह के मामले के लिए इसे अधिक रक्षात्मक होने की आवश्यकता है, और उसके बाद फॉल-बैक वैध (यदि अजीब) मूल्य पर विफल नहीं होता है, तो गैर-प्रतिबिंब दृष्टिकोण का उपयोग करना होगा, जब आप दोबारा प्रतिक्रिया करेंगे तो इसका मतलब होगा कि आप चाहते हैं फिर प्रतिबिंब बिट हटाएं जब तक कि यह काफी तेज़ नहीं था। - Jon Hanna
@ जोन: मैं नहीं देखता कि कैसे एनम के प्रकार में संभवतः इसके लिए कोई प्रविष्टि नहीं हो सकती है। मैं क्या खो रहा हूँ? संपादित करें: गोटो, एनम ऑरड झंडे हो सकते हैं। मैं आपकी टिप्पणी के साथ सहमत हूं। - spender
यह सबसे आम मामला है। अंतर्निहित प्रकार के किसी भी मूल्य को एक enum प्रकार में डालने के लिए भी मान्य है, इसलिए Enum.IsDefined () मौजूद है ताकि किसी को ऐसे मामलों को पकड़ने की अनुमति मिल सके जहां यह किसी विधि के लिए अमान्य तर्क होगा या किसी संपत्ति के लिए अमान्य मान होगा। - Jon Hanna


यदि आप चाहते थे, तो आप सभी विधियों के लिए एक्सटेंशन विधि का काम कर सकते हैं:

public static string ToValueString(this Enum enumValue) 
{
    if (enumValue.GetType().GetEnumUnderlyingType() == typeof(int))
        return ((int)(object)enumValue).ToString();
    else if (enumValue.GetType().GetEnumUnderlyingType() == typeof(byte))
        return ((byte)(object)enumValue).ToString();
    ... 
}        

2
2017-08-09 22:41



+1: दिलचस्प ... लेकिन एक ही समय में डबल कास्ट देखने के लिए थोड़ा असामान्य। अच्छी चाल। :) इसका उपयोग किया जा सकता था Enum के बजाय T where T : struct? - Mark Byers
आप सही हे। यकीन नहीं है कि मैंने सोचा था कि उस मामले में मददगार था। अपने सुझाव को प्रतिबिंबित करने के लिए इसे बदल दिया। - Kirk Woll


महान सामान ... मैंने अब अपनी परियोजना में एक विस्तार विधि जोड़ा है

public static class EnumExtensions 
{ 
    public static string NumberString(this Enum enVal) 
    { 
        return enVal.ToString("D"); 
    }
} 

अब मैं int मूल्य प्राप्त कर सकता हूं - एक स्ट्रिंग के रूप में - कॉल करके Urgency.Routine.NumberString(); फ्रैंकेंटोश और जॉन के लिए धन्यवाद :)


2
2017-08-10 01:47





आप अपने विशिष्ट प्रकार के लिए एक एक्सटेंशन विधि लिख सकते हैं:

public static class UrgencyExtension
{
    public static string ToIntegerString(this Urgency u)
    {
        return ((int)u).ToString();
    }
}

निम्नानुसार उपयोग करें:

Urgency u = Urgency.Routine;
string s = u.ToIntegerString();

1
2017-08-09 22:38