2010-03-31 12 views
8

मैं इस तरह enum है:enum को स्ट्रिंग में कनवर्ट करने का सबसे अच्छा तरीका क्या है?

public enum ObectTypes 
{ 
    TypeOne, 
    TypeTwo, 
    TypeThree, 
    ... 
    TypeTwenty 
} 

तो मैं स्ट्रिंग को यह enum बदलना होगा। अब मैं इस तरह कर रही है: बेहतर तरीका यह है है

public string ConvertToCustomTypeName(ObjectTypes typeObj) 
{ 
    string result = string.Empty; 
    switch (typeObj) 
    { 
     case ObjectTypes.TypeOne: result = "This is type T123"; break; 
     case ObjectTypes.TypeTwo: result = "Oh man! This is type T234"; break; 
     ... 
     case ObjectTypes.TypeTwenty: result = "This is type last"; break; 
    } 

    return result; 
} 

इम काफी यकीन है कि वहाँ, मैं कुछ अच्छा अभ्यास समाधान की तलाश में।

EDIT: परिणाम स्ट्रिंग में कोई भी पैटर्न नहीं है।

अग्रिम धन्यवाद।

+0

इसके अलावा FWIW आपको परिणाम ऑब्जेक्ट की आवश्यकता नहीं है, बस आप उन तारों को वापस कर दें और ब्रेक स्टेटमेंट से छुटकारा पाने में भी सक्षम हों। –

+0

@ क्रिस मैरिसिक। हां, आपके पास सही है, लेकिन वह चर केवल बेहतर पढ़ने के लिए है :-) – Dariusz

उत्तर

19

मैं से [Description] विशेषता का उपयोग System.ComponentModel

उदाहरण:

public enum RoleType 
{ 
    [Description("Allows access to public information")] Guest = 0, 
    [Description("Allows access to the blog")] BlogReader = 4, 
} 

तो यह से पढ़ने के लिए मैं

public static string ReadDescription<T>(T enumMember) 
{ 
    var type = typeof (T); 

    var fi = type.GetField(enumMember.ToString()); 
    var attributes = (DescriptionAttribute[]) 
      fi.GetCustomAttributes(typeof (DescriptionAttribute), false); 
    return attributes.Length > 0 ? 
     attributes[0].Description : 
     enumMember.ToString(); 
} 

कर फिर उपयोग

ReadDescription(RoleType.Guest);

नोट: इस समाधान के रूप में कुछ भी नहीं एक ही संस्कृति आवेदन मान लिया गया है विशेष रूप से कई संस्कृतियों के बारे में पूछा गया था। यदि आप ऐसी स्थिति में हैं जहां आपको कई संस्कृतियों को संभालने की आवश्यकता है, तो मैं DescriptionAttribute या संस्कृति की जागरूक संसाधन फ़ाइल की कुंजी स्टोर करने के समान ही उपयोग करूंगा। जबकि आप enres सदस्य को सीधे .resx फ़ाइल में संग्रहीत कर सकते हैं जो सबसे सख्त युग्मन संभव बना देगा। मुझे कोई कारण नहीं दिख रहा है कि आप अंतर्राष्ट्रीयकरण उद्देश्यों के लिए मौजूद प्रमुख मूल्यों के लिए अपने आवेदन (एनम सदस्य नाम) की आंतरिक कार्यवाही को क्यों जोड़ना चाहते हैं।

+3

यह बहुत धीमा है - उपयोग के आधार पर, इससे कोई फर्क नहीं पड़ता। –

+6

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

+0

यह enums से निपटने के लिए एक महान तकनीक है, हालांकि यह बहुत साफ होगा अगर enum के पास ' GetDescription' विधि या कुछ ऐसे (और यदि आप विवरण * के बाद * विवरण डाल सकते हैं)। – MusiGenesis

2

मुझे लगता है कि सबसे आसान तरीका यह है कि एक ऐसा फ़ंक्शन है जो enum value और पसंदीदा शॉर्ट नाम के बीच मैप करता है और फिर एक और फ़ंक्शन बनाता है जो पूर्ण संदेश उत्पन्न करता है।

internal static string MapToName(ObjectTypes value) { 
    switch (value) { 
    case ObjectTypes.TypeOne: return "T123"; 
    case ObjectTypes.TypeTwo: return "T234"; 
    ... 
    } 
} 

public string ConvertToCustomTypeName(ObjectTypes value) { 
    return String.Format("This is type {0}", MapToName(value)); 
} 
+0

यह स्पष्ट है कि वह इसे कुछ मनमाने ढंग से स्ट्रिंग में परिवर्तित करना चाहता है, न कि enum फ़ील्ड का नाम। –

+0

@ मत्ती, धन्यवाद, धन्यवाद। अद्यतन उत्तर – JaredPar

+0

उपसर्ग 'निरंतर नहीं है, प्रत्यय भी स्थिर नहीं है, इसलिए मैं स्ट्रिंग की शुरुआत की भविष्यवाणी नहीं कर सकता। – Dariusz

9

यदि आपको कस्टम स्ट्रिंग की आवश्यकता है, तो सबसे अच्छा विकल्प Dictionary< ObjectTypes, string> बनाना होगा, और बस एक शब्दकोश लुकअप करें।

आप डिफ़ॉल्ट toString() कार्यक्षमता के साथ ठीक कर रहे हैं, सिर्फ typeObj.ToString();

का उपयोग शब्दकोश दृष्टिकोण के लिए, आप कर सकता है:

private static Dictionary<ObjectTypes, string> enumLookup; 

static MyClass() 
{ 
    enumLookup = new Dictionary<ObjectTypes, string>(); 
    enumLookup.Add(ObjectTypes.TypeOne, "This is type T123"); 
    enumLookup.Add(ObjectTypes.TypeTwo, "This is type T234"); 
    // enumLookup.Add... 

} 

आपका विधि हो जाता है:

public string ConvertToCustomTypeName(ObjectTypes typeObj) 
{ 
    // Shouldn't need TryGetValue, unless you're expecting people to mess with your enum values... 
    return enumLookup[typeObj]; 
} 
+0

मुझे यह इंगित करने की आवश्यकता है कि कॉम्पैक्ट एनम्स (कोई बड़ा मूल्य अंतराल नहीं), एक सूची अधिक कुशल होगी। –

+0

@ सिमॉन: हां, संभावित रूप से - यद्यपि यह अधिक लचीला है, किसी भी मूल्यवान प्रकार के लिए, किसी भी मनमानी enum मूल्य के साथ ... –

+0

@ सिमॉन: हालांकि, यह केवल सच है, अगर enum मानों को शुरू या निकट 0 ... आप "मान" प्राप्त करना शुरू करते हैं जिसे आसानी से सूची सूचकांक में परिवर्तित नहीं किया जा सकता है, और हैशिंग तेजी से हो जाएगी। –

1

मैंने एक बार एनम फ़ील्ड पर एक कस्टम विशेषता का उपयोग किया जो स्ट्रिंग पैरामीटर लेता था और फिर एनम वैल्यू दिए जाने पर स्ट्रिंग निकालने के लिए एक फ़ंक्शन लिखा था।

+0

हू, एनम सदस्यों को नहीं पता था :)। –

0

यह रिफैक्टरिंग के लिए कॉल करता है, मैं कहूंगा।

Replace Type Code With Class

+0

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

1

आप बस enum के नाम (यानी TypeOne) आप बस enum पर ही toString() कॉल कर सकते हैं उपयोग करना चाहते हैं

typeObj.ToString() 

आप एक कस्टम के आधार पर स्ट्रिंग चाहते हैं टाइप करें कि आपके पास कई अलग-अलग विकल्प हैं। आपके पास स्विच स्टेटमेंट ठीक है लेकिन अगर आप बड़ी संख्या में enums हैं तो इसे बनाए रखना गन्दा हो जाएगा। या आप enum प्रकार का उपयोग करके कुंजी और स्ट्रिंग मान के रूप में आधारित एक शब्दकोश सेट कर सकते हैं।

public enum ObectTypes 
{ 
    One, 
    Two 
} 

Dictionary<ObectTypes, String> myDic = new Dictionary<ObectTypes, string>(); 
myDic.Add(ObectTypes.One, "Something here for One"); 
myDic.Add(ObectTypes.Two, "Something here for Two"); 
1

मैं इस पर विश्वास नहीं कर सकता ... किसी ने संसाधन फ़ाइल का सुझाव क्यों नहीं दिया है?

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

+1

मुझे नहीं लगता कि कई सी # प्रोग्रामर संसाधन फ़ाइल का उपयोग करते हैं। ऐसा लगता है कि सी ++/win32/एमएफसी कोडर हैं जो संसाधन फ़ाइल की रोशनी देखते हैं। – Justin

+0

@ जस्टिन - मैं सहमत हूं कि पर्याप्त लोग उनका उपयोग नहीं कर रहे हैं, संभावित रूप से वीबी 6 कोड करने के पुराने दिनों से एक बुरी आदत छोड़ दी गई है। मुझे लगता है कि जितना अधिक लोग व्यापार तर्क से यूआई को सही ढंग से अलग करने के बारे में जागरूक हो जाते हैं (यानी एमवीवीएम पैटर्न) तो लोग संसाधन फ़ाइलों का अधिक उपयोग करना शुरू कर देंगे, खासकर क्योंकि संसाधन फ़ाइलों को स्थिर बाध्यकारी के हिस्से के रूप में उपयोग किया जा सकता है। – slugster

+0

-1 मैं इस बात से असहमत हूं कि यह बुरा अभ्यास है, मैंने इस विधि का उपयोग बिना दर्द के वर्षों तक किया है। एकमात्र समय यह समझ में नहीं आता है कि अगर सूची गतिशील और अक्सर परिवर्तनों से होती है, तो उस बिंदु पर विवरण विवरणों का उपयोग किए बिना समझ में नहीं आता है या नहीं। –

4

सुझाव संसाधन रास्ते का उपयोग करें:

string GetName(Enum e) { 
    return Properties.Resources.ResourcesManager.GetString("_enum_"+e.GetType().ToString().Replace('.','_')); 
} 

त्रुटि निवारण थोड़ा अधिक है ..

1

मैं एक डेटाबेस में इन मूल्यों को जाते थे। भूमिकाओं आम तौर पर इन सहित कई कारणों के लिए एक डेटाबेस में हैं:

  1. रिपोर्ट भूमिकाओं के खिलाफ चलाने के लिए, इस प्रकार वर्णन प्रदर्शित करने के लिए एक की जरूरत पड़ सकती है।
  2. भूमिका परिभाषाओं को नए कोड को तैनात किए बिना कॉन्फ़िगर किया जा सकता है।
  3. भूमिकाओं को एक प्रमुख बाधा के साथ लागू किया जाना चाहिए।

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

यदि आप इसे काम करने के लिए अपने आप को एक एनम के आसपास हैक करना चाहते हैं, तो शायद आपको एनम का उपयोग नहीं करना चाहिए। उचित प्लेसमेंट को देखते हुए, कोड में बहुत कम या कोई हैक्स के साथ सब कुछ बेहतर प्रवाह करना चाहिए। अनुमोदित Enums उनकी जगह है; उदाहरण के लिए, बल्कि एक स्थिर पारस्परिक रूप से अनन्य स्थिति।

0

जो आप पहले से उपयोग कर रहे थे वह खराब पैटर्न नहीं है। लगभग हर दूसरे विकल्प में अपनी समस्याएं होती हैं। एफ # पैटर्न मिलान के साथ, आप आप एक सरल सी # स्विच बयान के साथ की तुलना में एक बहुत अधिक नियंत्रण है

type ObjectTypes = 
| TypeOne 
| TypeTwo 
| TypeThree 
... 
| TypeTwenty 
with override this.ToString() = 
    match this with 
    | TypeOne -> "This is type T123" 
    | TypeTwo -> "Oh man! This is type T234" 
    ... 
    | TypeTwenty -> "This is type last" 
    | _ -> "This is any other type that wasn't explicitly specified" 

बेशक,: यदि आप इस प्रकार के लिए एफ # इस्तेमाल कर रहे थे, तो आप की तरह कुछ कर सकता है।

संबंधित मुद्दे

 संबंधित मुद्दे