परिवर्तित Enum को स्ट्रिंग


163

.NET 3.5 में Enum को String में बदलने का पसंदीदा तरीका कौन सा है?

  • Enum.GetName
  • Enum.Format
  • तार

मुझे इनमें से किसी एक को क्यों पसंद करना चाहिए? क्या कोई बेहतर प्रदर्शन करता है?


10
मैंने खोजा और एक डुप्लिकेट खोजने में असमर्थ था। यदि आप एक लिंक प्रदान कर सकते हैं तो मैं इस प्रश्न को हटा दूंगा।
एरिक वील्नाउ

1
कभी-कभी, एक स्विच स्टेटमेंट का उपयोग करना सबसे अच्छा अभ्यास नहीं है (जब आपके पास बड़ी गणना है) तो आप डिक्ट <> का उपयोग कर सकते हैं
लड़के एल

1
यदि आप बेहतर प्रदर्शन चाहते हैं तो आप इस आलेख में वर्णित वर्ग का उपयोग कर सकते हैं कोडप्रोजेक्ट . com /KB/ dotnet/enum.aspx । प्रयोग इस Enum <YourEnum> .ToString (yourValue) या Enum तरह दिखेगा <YourEnum> .ToString ((int) yourValue)
ideafixxxer

5
डॉटफेकेशन को नहीं तोड़ने के लिए कोडिंग कुत्ते को छेड़ने वाली पूंछ का प्रतीक है। एसडब्ल्यू निर्माता यह नहीं सोच रहे हैं, "चलो एक महान ऐप बनाते हैं ताकि डॉटफसकेटर के पास कुछ करना है।" एसओपी विकास को सुविधाजनक बनाने में मदद करने के लिए डूफसकेटर मौजूद है। अगर यह ऐसा नहीं कर सकता ... यह कर सकते हैं!
micahhoover

जवाबों:


126

सी # 6 के रूप में एक एनम का नाम पाने का सबसे अच्छा तरीका नया nameofऑपरेटर है:

nameof(MyEnum.EnumValue);

// Ouputs
> "EnumValue"

यह संकलित समय पर काम करता है, संकलित परिणाम में स्ट्रिंग द्वारा प्रतिस्थापित किया जा रहा है, जो बदले में इसका मतलब है कि यह सबसे तेज़ तरीका संभव है।

एनम नामों का कोई भी उपयोग कोड ऑब्सफैक्शन के साथ हस्तक्षेप नहीं करता है, यदि आप एनम नामों के स्थापन को सार्थक या महत्वपूर्ण मानते हैं - तो यह संभवतः एक संपूर्ण अन्य प्रश्न है।


11
यह अधिक ध्यान देने योग्य है। स्पष्ट सीमा के बावजूद, संकलन समय इनपुट के लिए आवश्यकता है। मेरी राय में जब भी संभव हो इसे प्राथमिकता दी जानी चाहिए । 'नाम बदलें' और 'सभी संदर्भों को ढूंढें' इसे ध्यान में रखें, संभवतः जादू के तार और डुप्लिकेट स्थिरांक से बचें।
तिमो

1
तो मुझे लगता है कि यह काम नहीं करेगा जब एनम वैल्यू को रनटाइम पर परिभाषित किया जाता है? Ex: MyEnum variableEnum; variableEnum = setEnumValueMethod (); nameof (variableEnum);
मैक्स्टर

1
@ मैक्सटर नं, जैसा nameof(variableEnum)होगा "variableEnum"। यह क्षेत्र (संपत्ति / समय / पैराम / चर ) का नाम दर्शाता है ( मूल्य नहीं) ।
कीथ

तु। यदि आप ऐसा करते हैं तो दुर्भाग्य से काम नहीं करता है: var someEnumvalue = SomeEnum.FooBar; nameof (someEnumvalue);
संभवतः

1
@ निश्चित रूप से हाँ, यह वापस आ जाएगा "someEnumValue", जबकि आपको nameof(SomeEnum.FooBar)प्राप्त करने की आवश्यकता होगी "FooBar"
कीथ

93

हमारी परियोजना के लिए काम करता है ...

public static String convertToString(this Enum eff)
{
    return Enum.GetName(eff.GetType(), eff);
}

public static EnumType converToEnum<EnumType>(this String enumValue)  
{
    return (EnumType) Enum.Parse(typeof(EnumType), enumValue);
}

7
Enum.GetName ऑब्जेक्ट तर्क के रूप में मान लेता है। इसका मतलब है कि मूल्य को बॉक्स किया जाएगा और यह आवंटन पर और कचरा संग्रह पर सीपीयू संसाधनों को बर्बाद करेगा। यदि यह बहुत समय के लिए किया जाता है, तो Enum.GetName में एक शब्दकोश में मूल्यों को कैशिंग करने और नाम की तलाश करने की तुलना में बहुत कम थ्रूपुट होगा।
रैन

@ तो क्या समाधान है, जो बजाय उपयोग करने के लिए?
शैजुट

इसका उत्तर होना चाहिए
संभवतः

मेरे प्रोजेक्ट को धीमा बनाता है। .String () तेज है।
d2k2

29

मेरे परीक्षणों में, Enum.GetNameतेज और सभ्य मार्जिन के द्वारा किया गया था। आंतरिक रूप से ToStringकॉल करता है Enum.GetName। .NET 4.0 के लिए स्रोत से , आवश्यक:

public override String ToString()
{
     return Enum.InternalFormat((RuntimeType)GetType(), GetValue());
}

private static String InternalFormat(RuntimeType eT, Object value)
{
    if (!eT.IsDefined(typeof(System.FlagsAttribute), false))
    {
        String retval = GetName(eT, value); //<== the one
        if (retval == null)
            return value.ToString();
        else
            return retval;
    }
    else
    {
        return InternalFlagsFormat(eT, value);
    }
}

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

टेस्ट सेटअप : 8 मानों के साथ एनम, नं। पुनरावृत्तियों का = १००००००

परिणाम : Enum.GetName => 700 ms, ToString => 2000 ms

यदि गति ध्यान देने योग्य नहीं है, तो मैं इसकी देखभाल और उपयोग नहीं करूंगा ToStringक्योंकि यह बहुत अधिक क्लीनर कॉल प्रदान करता है। कंट्रास्ट

Enum.GetName(typeof(Bla), value)

साथ में

value.ToString()

25

Enum.GetName (...)

यह सबसे सुंदर तरीका है जो इसके लिए है।

var enumValueString = Enum.GetName(typeof (MyEnum), MyEnum.MyValue);

हालाँकि मुझे कॉलिंग के साथ कोई समस्या नहीं दिख रही है .ToString()क्योंकि यह केवल छोटा है।

var enumValueString = MyEnum.MyValue.ToString();

नए C # 6 सिंटैक्स के साथ आप इसका उपयोग कर सकते हैं:

nameof(MyEnum.MyValue)

20

इन सभी को आंतरिक रूप से एक विधि कहा जाता है InternalGetValueAsString। के बीच का अंतर ToStringऔर GetNameहो सकता है कि GetNameपहले कुछ चीजें सत्यापित करने के लिए है:

  1. आपके द्वारा दर्ज किया गया प्रकार शून्य नहीं है।
  2. आपके द्वारा दर्ज किया गया प्रकार वास्तव में एक ज्ञान है।
  3. आपके द्वारा दिया गया मान शून्य नहीं है।
  4. आपके द्वारा पास किया गया मान एक प्रकार का होता है, जो एक एन्यूमरेशन वास्तव में अंतर्निहित प्रकार, या एन्यूमरेशन के प्रकार के रूप में उपयोग कर सकता है। इसे GetTypeजांचने के लिए इसका उपयोग मूल्य पर किया जाता है।

.ToStringइन उपरोक्त मुद्दों में से किसी के बारे में चिंता करने की ज़रूरत नहीं है, क्योंकि इसे स्वयं कक्षा के एक उदाहरण पर कहा जाता है, और संस्करण में पारित नहीं होने पर, इसलिए, इस तथ्य के कारण कि .ToStringविधि में एक ही सत्यापन समस्या नहीं है स्थिर तरीकों के रूप में, मैं निष्कर्ष निकालूंगा कि .ToStringएक स्ट्रिंग के रूप में मूल्य प्राप्त करने का सबसे तेज़ तरीका है।


2
आपने इनकी जाँच कहाँ की? विधानसभा संस्करण क्या था? मुझे बहुत अलग परिणाम मिलते हैं।
नवफल

17

सबसे अच्छा मुझे मिल सकता है यह MSDN पर असंबंधित प्रश्न है , जिसमें एक XML स्निपेट शामिल है जो इस प्रश्न का उत्तर देता है। इनमें से कोई भी विधि समान दोष साझा करती है: वे कॉल करते हैं enum.toString(), जो डॉटफ़सकेशन का उपयोग करते समय ठीक से काम नहीं करते हैं । अन्य चिंताएं अप्रत्यक्ष मुक्केबाजी (गेटनेम और प्रारूप) से संबंधित हैं। दुर्भाग्य से, मैं ऊपर दिए गए किसी भी उपयोग के लिए कोई प्रदर्शन कारण नहीं खोज सकता।

एक्सएमएल स्निपेट से पैराफ्रेसिंग ,

एक बॉक्सिंग एनम को स्ट्रिंग करने के लिए पास करना। फ़र्मैट () या किसी अन्य फ़ंक्शन को enum.ToString()कॉल किया जा सकता है। इससे डॉटफ़स्कैटिंग करने पर समस्या होगी। आप उपयोग नहीं करना चाहिए enum.ToString(), enum.GetNames(), enum.GetName(), enum.Format()या enum.Parse()एक स्ट्रिंग के लिए एक enum कन्वर्ट करने के लिए। इसके बजाय, एक स्विच स्टेटमेंट का उपयोग करें, और यदि आवश्यक हो तो नामों का अंतर्राष्ट्रीयकरण भी करें।


16

Enum.GetName()

Format()वास्तव में GetName()कुछ स्वरूपण कार्यक्षमता (या InternalGetValueAsString()सटीक होना) के साथ वास्तव में सिर्फ एक आवरण है । ToString()के रूप में बहुत ज्यादा है Format()। मुझे लगता GetName()है कि यह सबसे अच्छा विकल्प है क्योंकि यह पूरी तरह से स्पष्ट है कि यह स्रोत पढ़ने वाले किसी भी व्यक्ति के लिए क्या करता है।


8

मैं एक "विवरण" एक्सटेंशन विधि बनाता हूं और इसे एनम के साथ संलग्न करता हूं ताकि मैं वास्तव में उपयोगकर्ता के अनुकूल नामकरण प्राप्त कर सकूं जिसमें रिक्त स्थान और आवरण शामिल हैं। मैं कभी भी प्रदर्शन योग्य पाठ के रूप में एनम मूल्य का उपयोग करना पसंद नहीं करता हूं क्योंकि यह कुछ ऐसा है जिसे डेवलपर्स हम अधिक पठनीय कोड बनाने के लिए उपयोग करते हैं। यह यूआई प्रदर्शन उद्देश्यों के लिए अभिप्रेत नहीं है। मैं यूआई को बदलने में सक्षम होना चाहता हूं और सभी जगहों पर दुश्मनी को बदल सकता हूं।


6

मुझे नहीं पता कि "पसंदीदा" विधि क्या है (100 लोगों से पूछें और 100 अलग-अलग राय लें) लेकिन क्या सरल है और क्या काम करता है। GetNameकाम करता है लेकिन बहुत अधिक कीस्ट्रोक्स की आवश्यकता होती है। ToString()लगता है कि काम बहुत अच्छा है।


1

VB aficionados के लिए:

EnumStringValue = System.Enum.GetName(GetType(MyEnum), MyEnumValue)

0

यह भी काम करेगा।

    List<string> names = Enum.GetNames(typeof(MyEnum)).ToList();

0

ToString()एक पठनीयता के दृष्टिकोण से सबसे स्पष्ट परिणाम देता है, जबकि उपयोग Enum.GetName()करने के लिए थोड़ा और अधिक मानसिक रूप से समझने की आवश्यकता होती है कि वह क्या करने की कोशिश कर रहा है (जब तक कि आप हर समय पैटर्न नहीं देखते)।

शुद्ध प्रदर्शन के दृष्टिकोण से, जैसा कि पहले से ही @ नवाफ के जवाब में प्रदान किया गया है, Enum.GetName()बेहतर है।

यदि प्रदर्शन वास्तव में आपका लक्ष्य है, तो पहले से एक लुक-अप प्रदान करना बेहतर होगा (एक शब्दकोश या कुछ अन्य मानचित्रण का उपयोग करके)।

C ++ / CLI में, यह ऐसा दिखेगा

Dictionary<String^, MyEnum> mapping;
for each (MyEnum field in Enum::GetValues(MyEnum::typeid))
{
    mapping.Add(Enum::GetName(MyEnum::typeid), field);
}

100 वस्तुओं और 1000000 पुनरावृत्तियों की गणना के साथ तुलना:

Enum.GetName: ~ 800ms
.ToString (): ~ 1600ms
शब्दकोश मानचित्रण: ~ 250ms


-3

सरल: सूची में नाम का नाम:

List<String> NameList = Enum.GetNames(typeof(YourEnumName)).Cast<string>().ToList()

हाय @Brian, मुझे नहीं लगता कि आपको GetNames ()
निक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.