2011-03-31 22 views
26

से Enum को विस्तार विधि को कार्यान्वित करना चाहते हैं, जो enum को शब्दकोश में परिवर्तित करता है।शब्दकोश

public static Dictionary<int, string> ToDictionary(this Enum @enum) 
      { 
       Type type1 = @enum.GetType(); 
       return Enum.GetValues(type1).Cast<type1>() 
        //.OfType<typeof(@enum)>() 
        .ToDictionary(e => Enum.GetName(@enum.GetType(), e)); 
      } 

यह संकलित क्यों नहीं करता है?

कोई त्रुटि

"प्रकार या नाम स्थान का नाम 'type1' नहीं पाया जा सका (यदि आप एक निर्देश या एक विधानसभा संदर्भ का उपयोग करते हुए याद कर रहे हैं?)"

+2

क्यों आप हमें त्रुटि संदेश दिखाई नहीं है? –

उत्तर

48

Jon Skeet has written everything you need;)

लेकिन यहाँ आप अपने कोड है कि काम कर रहा है:

public static Dictionary<int, string> ToDictionary(this Enum @enum) 
{ 
    var type = @enum.GetType(); 
    return Enum.GetValues(type).Cast<int>().ToDictionary(e => e, e => Enum.GetName(type, e)); 
} 
+0

हाँ, यह अच्छा है! – Alexandre

+1

आप '' के बजाय 'कास्ट ' लिखकर थोड़ा सा सरल बना सकते हैं, क्योंकि तब आप पहले लैम्ब्डा-अभिव्यक्ति में ऑब्जेक्ट से int तक जा सकते हैं। –

+0

हाँ, आप सही :) अच्छी टिप्स :) Thx –

4

आप कर सकते हैं टाइप 1 को सामान्य पैरामीटर के रूप में उपयोग न करें, क्योंकि यह एक चर है, एक प्रकार नहीं।

public static Dictionary<string, TEnum> ToDictionary<TEnum>() 
    where TEnum : struct 
{ 
    if (!typeof(TEnum).IsEnum) 
     throw new ArgumentException("Type must be an enumeration"); 
    return Enum.GetValues(typeof(TEnum)).Cast<TEnum>(). 
      ToDictionary(e => Enum.GetName(typeof(TEnum), e)); 
} 

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

निम्नलिखित कोड कुछ क्या अपने कोड से पता चलता के समान होता है

ToDictionary<Colors>() 

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

+0

यह मेरी अपेक्षा नहीं है। मैं विस्तार विधि का उपयोग करना चाहता हूँ। – Alexandre

+0

अपने उपयोग और अपेक्षित आउटपुट का कोड नमूना दिखाएं। (क्योंकि यह एक विस्तार विधि के रूप में इसे लागू करने के लिए समझ में नहीं आता है) –

+1

@Alex Maslakov: एक विस्तार विधि वास्तव में उपयुक्त नहीं है क्योंकि आप स्थिर रूप से उपलब्ध enum के बारे में डेटा से एक शब्दकोश बना रहे हैं (यानी यह एक विशेष enum मान के गुणों का उपयोग करने के बजाय enum प्रकार परिभाषा में डेटा है)। एक्सटेंशन विधियां एक प्रकार के उदाहरण पर चलती हैं। –

12

ठीक है, आप वैरिएबल प्रकार Type का उपयोग सामान्य प्रकार तर्क के रूप में करने का प्रयास कर रहे हैं। आप जेनेरिक के साथ ऐसा नहीं कर सकते हैं, जो लगभग संकलन-समय प्रकार हैं।

आप इसे प्रतिबिंब के साथ कर सकते हैं, लेकिन यह एक सामान्य विधि बनाना बेहतर होगा। दुर्भाग्य से आप एक enum होने के लिए एक सामान्य प्रकार पैरामीटर को बाधित नहीं कर सकते हैं, हालांकि मेरे पास Unconstrained Melody में काम करने के लिए कुछ हैक्स हैं।

विफल होने पर, आप एक सामान्य विधि के लिए केवल struct प्रकार की बाधा का उपयोग कर सकते हैं जो एक अच्छी शुरुआत होगी। लेकिन एक enum के मूल्योंint मान नहीं हैं -

अब, अगले समस्या यह है कि आप एक Dictionary<int, string> प्राप्त करने की कोशिश कर रहे हैं। वे परिवर्तनीय से int मान हो सकते हैं, लेकिन वे तुरंत वहां नहीं हैं। ऐसा करने के लिए आप Convert.ToInt32 का उपयोग कर सकते हैं, लेकिन आपको कुछ करना होगा।

अंत में (इस पल के लिए) uint या long अंतर्निहित प्रकार का उपयोग करके आप enum के साथ क्या होने की उम्मीद करेंगे?

1

यहाँ विस्तार विधि मैं enumerations कन्वर्ट करने के लिए इस्तेमाल करते हैं, फर्क सिर्फ इतना है कि मैं अपने उद्देश्य के लिए IEnumerbale> लौटने रहा है:

public static IEnumerable<KeyValuePair<int, string>> ToListOfKeyValuePairs<TEnum>(this TEnum enumeration) where TEnum : struct 
{ 
    return from TEnum e in Enum.GetValues(typeof(TEnum)) 
      select new KeyValuePair<int, string> 
       (
        (int)Enum.Parse(typeof(TEnum), e.ToString()), 
        Regex.Replace(e.ToString(), "[A-Z]", x => string.Concat(" ", x.Value[0])).Trim() 
       ); 
} 

यह भी मूल्य के लिए रिक्त स्थान कहते हैं।

उदाहरण:

enum Province 
{ 
    BritishColumbia = 0, 
    Ontario = 1 
} 

उपयोग:

<select> 
<% foreach(var item in Province.BritishColumbia.ToListOfKeyValuePairs()){ %> 
    <option value="<%=item.Key %>"><%=item.Value %></option> 
<% } %> 
</select> 

आउटपुट:

<select> 
    <option value="0">British Columbia</option> 
    <option value="1">Ontario</option> 
</select> 

हालांकि @Paul Ruane सही है मैं यह एक बहुत ही उपयोगी विस्तार विधि के लिए मिल गया है। यह एक आदर्श दुनिया नहीं है।

2

डैनियल समाधान के आधार पर

public static SelectList ToSelectList<TEnum>(this HtmlHelper h) where TEnum : struct 
{ 
return new SelectList(FortunaExtension.ToDictionary<TEnum>(), "Key", "Value"); 
} 
संबंधित मुद्दे