2009-05-26 3 views
80

मैं किसी भी सिस्टम को परिवर्तित करने के लिए एक सामान्य विधि बनाना चाहता हूं। एनम व्युत्पन्न प्रकार को इसके संबंधित पूर्णांक मान में, कास्टिंग किए बिना और अधिमानतः स्ट्रिंग को पार्स किए बिना।System.Enum से बेस पूर्णांक में कैसे परिवर्तित करें?

जैसे, क्या मैं चाहता हूँ कुछ इस तरह है:

// Trivial example, not actually what I'm doing. 
class Converter 
{ 
    int ToInteger(System.Enum anEnum) 
    { 
     (int)anEnum; 
    } 
} 

लेकिन यह काम करने के लिए प्रकट नहीं होता। Resharper रिपोर्ट करता है कि आप 'int' टाइप करने के लिए 'System.Enum' प्रकार की अभिव्यक्ति नहीं डाल सकते हैं।

अब मैं इस समाधान के साथ आया हूं लेकिन मुझे कुछ और कुशल होना चाहिए।

class Converter 
{ 
    int ToInteger(System.Enum anEnum) 
    { 
     return int.Parse(anEnum.ToString("d")); 
    } 
} 

कोई सुझाव?

+1

मेरा मानना ​​है कि यह संकलक है जो शिकायत कर रहा है, न कि Resharper। – Kugel

+1

जरूरी नहीं है। मैं System.Enum पर एक विस्तार विधि है, और कभी कभी Resharper शिकायत करने का फैसला करता है: करने के लिए 'System.Enum' उदाहरण तर्क प्रकार 'Some.Cool.Type.That.Is.An.Enum' कनवर्ट नहीं कर सकता है जब यह निश्चित रूप से एक enum है अगर मैं कोड संकलित और चलाता हूं तो यह ठीक काम करता है। अगर मैं वीएस बंद कर देता हूं, रिशेर्पर कैश को उड़ाता हूं, और इसे वापस फायर करता हूं, तो सब कुछ ठीक हो जाने पर ठीक हो जाता है। मेरे लिए यह किसी प्रकार का कैश स्नफू है। उसके लिए भी वही हो सकता है। – Mir

+0

@ मिर मैंने रीशेपर को "शिकायत" भी दी है। मेरे लिए वही तय करें। यह सुनिश्चित नहीं है कि इन प्रकारों को मिश्रित क्यों किया जाता है, लेकिन यह निश्चित रूप से संकलक नहीं है। – akousmata

उत्तर

114

कास्ट किए जाने नहीं करना चाहते हैं,

Convert.ToInt32() 

चाल कर सकता है।

प्रत्यक्ष कलाकार ((int)enumValue के माध्यम से) संभव नहीं है। ध्यान दें कि यह भी "खतरनाक" होगा क्योंकि एक enum के विभिन्न अंतर्निहित प्रकार (int, long, byte ...) हो सकता है।

अधिक औपचारिक रूप से: System.EnumInt32 साथ कोई सीधा संबंध विरासत (हालांकि दोनों ValueType रों कर रहे हैं) है, तो स्पष्ट डाली प्रकार प्रणाली

+2

'कनवर्टर। ToInteger (MyEnum.MyEnumConstant); 'आपको कोई त्रुटि नहीं मिलेगी। कृपया उस भाग को संपादित करें। – nawfal

+0

धन्यवाद, @nawfal, आप सही हैं। मैंने प्रतिक्रिया संपादित की (और कुछ नया सीखा :) :)) – MartinStettner

+0

काम नहीं कर रहा है अगर अंतर्निहित प्रकार 'int' –

1

एक System.Enum से एक int में कास्ट करना मेरे लिए ठीक काम करता है (यह MSDN पर भी है)। शायद यह एक रिशेर्पर बग है।

+1

आपके द्वारा उपयोग किए जाने वाले रनटाइम का कौन सा संस्करण? – JoshBerke

+2

लिंक उप प्रकार के 'System.Enum' का कास्टिंग दिखाता है, न कि' System.Enum'। – nawfal

+0

एक समान समस्या मेरे पास एक रिशेर्पर कैश स्नफू थी। वीएस बंद करना और रिशेर्पर कैश को हटाने से त्रुटि पूरी तरह से रुकने के बाद भी गायब हो गई। – Mir

34

मैं एक वस्तु और फिर कास्ट कर काम करने के लिए मिल गया के भीतर सही नहीं किया जा सकता एक int:

public static class EnumExtensions 
{ 
    public static int ToInt(this Enum enumValue) 
    { 
     return (int)((object)enumValue); 
    } 
} 

यह बदसूरत और शायद सबसे अच्छा तरीका नहीं है। मैं इसके साथ गड़बड़ कर रहा हूं, यह देखने के लिए कि क्या मैं कुछ बेहतर तरीके से आ सकता हूं ....

संपादित करें: बस उस कनवर्ट को पोस्ट करने वाला था। ToInt32 (enumValue) भी काम करता है, और ध्यान दिया कि मार्टिनस्टेटनर ने मुझे हराया इसके लिए

public static class EnumExtensions 
{ 
    public static int ToInt(this Enum enumValue) 
    { 
     return Convert.ToInt32(enumValue); 
    } 
} 

टेस्ट:

int x = DayOfWeek.Friday.ToInt(); 
Console.WriteLine(x); // results in 5 which is int value of Friday 

संपादित करें 2: टिप्पणी में, किसी ने कहा कि यह केवल सी # 3.0 में काम करता है। मैं सिर्फ इस तरह VS2005 में इस परीक्षण किया है और यह काम किया:

public static class Helpers 
{ 
    public static int ToInt(Enum enumValue) 
    { 
     return Convert.ToInt32(enumValue); 
    } 
} 

    static void Main(string[] args) 
    { 
     Console.WriteLine(Helpers.ToInt(DayOfWeek.Friday)); 
    } 
+0

से अलग है तो मैंने आपको +1 दिया लेकिन यह समाधान केवल सी # 3.0 और उच्चतर के साथ काम करने जा रहा है। – Vadim

+0

मुझे लगता है, यह केवल संकलक को संतुष्ट करता है। क्या आपने रनटाइम पर इसका परीक्षण किया था? मैं इस समारोह में कोई मूल्य नहीं दे सका ... – MartinStettner

+0

क्योंकि यह एक विस्तार विधि है? या सी # के पुराने संस्करणों में enums के बारे में कुछ अलग है? – BFree

-1

मत भूलना कि Enum प्रकार ही उस में स्थिर सहायक कार्यों का एक समूह है। यदि आप सब कुछ करना चाहते हैं तो enum के उदाहरण को इसके पूर्ण पूर्णांक प्रकार में परिवर्तित करना है, तो कास्टिंग शायद सबसे प्रभावी तरीका है।

मुझे लगता है कि रेसर्पर शिकायत कर रहा है क्योंकि एनम किसी विशेष प्रकार की गणना नहीं है, और गणना स्वयं स्केलर वैल्यूएट टाइप से प्राप्त होती है, न कि एनम।यदि आप एक सामान्य तरीके से अनुकूलनीय कास्टिंग की जरूरत है, मैं कहूंगा कि यह आप अच्छी तरह से सूट कर सकता है (ध्यान दें कि गणना प्रकार खुद भी सामान्य में शामिल है:

public static EnumHelpers 
{ 
    public static T Convert<T, E>(E enumValue) 
    { 
     return (T)enumValue; 
    } 
} 

यह तो की तरह इस्तेमाल किया जा सकता है:

public enum StopLight: int 
{ 
    Red = 1, 
    Yellow = 2, 
    Green = 3 
} 

// ... 

int myStoplightColor = EnumHelpers.Convert<int, StopLight>(StopLight.Red); 

मुझे यकीन है कि के लिए मेरे सिर के ऊपर से नहीं कह सकता, लेकिन इसके बाद के संस्करण कोड भी अनुमति देता है के बाद, सी # के प्रकार निष्कर्ष द्वारा समर्थित किया जा सकता है:

int myStoplightColor = EnumHelpers.Convert<int>(StopLight.Red); 
+1

दुर्भाग्यवश, आपके उदाहरण में ई हो सकता है किसी भी तरह का। जेनेरिक मुझे एनम का उपयोग टाइप पैरामीटर बाधा के रूप में करने की अनुमति नहीं देते हैं। मैं नहीं कह सकता: जहां टी: एनम – Vadim

+0

आप टी: संरचना कहां उपयोग कर सकते हैं। यह उतना सख्त नहीं है जितना आप चाहते हैं, लेकिन यह किसी भी संदर्भ प्रकार को काट देगा (जो मुझे लगता है कि आप क्या करने की कोशिश कर रहे हैं।) – jrista

+0

आप इसका उपयोग कर सकते हैं: अगर (! टाइपऑफ (ई) आईएसईएनम) नया फेंक दें ArgumentException ("ई एक गणित प्रकार होना चाहिए"); – diadiora

11

तुम क्यों वें बदलने की आवश्यकता क्यों है एक सहायक विधि के साथ ई पहिया? अपने अंतर्निहित प्रकार के लिए enum मान डालना पूरी तरह से कानूनी है।

यह कम लिखना है, और मेरी राय में, अधिक पठनीय उपयोग करने के लिए ...

int x = (int)DayOfWeek.Tuesday; 

... बल्कि कुछ तरह से ...

int y = Converter.ToInteger(DayOfWeek.Tuesday); 
// or 
int z = DayOfWeek.Tuesday.ToInteger(); 
+4

मैं किसी भी enum मान को परिवर्तित करना चाहता हूँ। हां, मेरे पास विभिन्न प्रकार के वर्ग हैं जिनमें enum फ़ील्ड हैं जिन्हें सामान्य रूप से कुछ कोड द्वारा संसाधित किया जा रहा है। यही कारण है कि int के लिए एक साधारण कलाकार उचित नहीं है। – orj

+0

@orj, मुझे सच में यकीन नहीं है कि आपका क्या मतलब है। क्या आप एक उदाहरण दे सकते हैं जो आपको आवश्यक उपयोग दिखा रहा है? – LukeH

+2

कभी-कभी आप सामान्य रूप से एक enum, जैसे कि सामान्य विधि के मामले में नहीं डाला जा सकता है। चूंकि जेनेरिक तरीकों को enums के लिए बाध्य नहीं किया जा सकता है, इसलिए आपने इसे संरचना की तरह कुछ सीमित कर दिया है, जिसे किसी int में नहीं डाला जा सकता है। उस स्थिति में, आप इसे करने के लिए Convert.ToInt32 (enum) का उपयोग कर सकते हैं। –

4

मेरा उत्तर here से:

Enum e = Question.Role; 
:

में के रूप में e को देखते हुए

फिर इन काम:

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

पिछले दो सादे बदसूरत हैं। पहला व्यक्ति अधिक पठनीय होना चाहिए, हालांकि दूसरा एक बहुत तेज़ है। या एक विस्तार विधि हो सकती है सर्वोत्तम, दोनों दुनिया के सर्वश्रेष्ठ।

public static int GetIntValue(this Enum e) 
{ 
    return e.GetValue<int>(); 
} 

public static T GetValue<T>(this Enum e) where T : struct, IComparable, IFormattable, IConvertible, IComparable<T>, IEquatable<T> 
{ 
    return (T)(object)e; 
} 

अब आप कॉल कर सकते हैं:

e.GetValue<int>(); //or 
e.GetIntValue(); 
+0

क्या आप वाकई दूसरा तेज है? मुझे लगता है कि यह enum बॉक्स होगा और फिर int में वापस unbox? – yoyo

+1

@योयो 'ई' वैरिएबल में पहले से ही वास्तविक मूल्य प्रकार, यानी enum का बॉक्सिंग उदाहरण है। जब आप 'Enum e = Question.Role लिखते हैं;' यह पहले से ही बॉक्स किया गया है। प्रश्न बॉक्सिंग 'System.Enum' को वापस अंतर्निहित int प्रकार (अनबॉक्सिंग) में परिवर्तित करने के बारे में है। तो यहां अनबॉक्सिंग केवल प्रदर्शन चिंता है। '(int) (ऑब्जेक्ट) ई' एक सीधा अनबॉक्स कॉल है; हां अन्य दृष्टिकोणों की तुलना में तेज़ होना चाहिए। [इसे देखें] (http://stackoverflow.com/questions/7995606/boxing-occurrence-in-c-sharp) – nawfal

+0

स्पष्टीकरण के लिए धन्यवाद। मैं गलत धारणा के तहत था कि System.Enum का एक उदाहरण एक अनबॉक्स किया गया मूल्य था। इसे भी देखें - http://msdn.microsoft.com/en-us/library/aa691158(v=vs.71).aspx – yoyo

8

आप उसके अंतर्निहित प्रकार (सभी नहीं enums int द्वारा समर्थन कर रहे हैं) के लिए किसी भी enum बदलने की आवश्यकता है, तो आप उपयोग कर सकते हैं:

return System.Convert.ChangeType(
    enumValue, 
    Enum.GetUnderlyingType(enumValue.GetType())); 
+4

यह एकमात्र बुलेटप्रूफ उत्तर है। –

+0

यह निश्चित रूप से स्वीकार्य उत्तर होना चाहिए। –