2010-11-04 18 views
7

पर एक enum सेट करें मुझे यकीन है कि यह काफी मामूली है लेकिन मैं इसे सही नहीं समझ सकता।अपने डिफ़ॉल्ट मान

public static string DoSomething(this Enum value) 
{ 
    if (!Enum.IsDefined(value.GetType(), value)) 
    { 
     // not a valid value, assume default value 
     value = default(value.GetType()); 
    } 

    // ... do some other stuff 
} 

लाइन value = default(value.GetType()); संकलन नहीं है, लेकिन उम्मीद है कि आप देख सकते हैं कि मैं क्या प्रयास कर रहा हूँ। मुझे Enum param को अपने स्वयं के प्रकार के डिफ़ॉल्ट मान पर सेट करने की आवश्यकता है।

+0

कैसे कर सकते हैं आप इस विधि को 'मान' के रूप में उसी प्रकार के मूल्य में परिभाषित किए गए 'मान' के बिना भी कॉल करते हैं? –

+0

@Paw, इस तरह enum काम करता है। आप इंट एनम में किसी भी int मान को स्टोर कर सकते हैं, चाहे वह परिभाषित हो या नहीं। – fearofawhackplanet

+0

@fearofawhackplanet, मैं बस यह समझने की कोशिश कर रहा हूं कि आप क्या करने की कोशिश कर रहे हैं। यदि आप एक इंट को एक enum या शायद एक स्ट्रिंग को एक enum में परिवर्तित करना चाहते हैं? –

उत्तर

1

Activator.CreateInstance(typeof(ConsoleColor)) काम करने के लिए

+0

इसके लिए आपको एक कठिन कलाकार की आवश्यकता है। (ConsoleColor) Activator.CreateInstance (typeof (ConsoleColor)) –

+0

@Paw, आप डर के उदाहरण (गतिशील प्रकार के साथ) –

+0

में ऐसा कैसे करेंगे, ऐसा नहीं है कि मुझे नहीं लगता कि यह एक्टिवेटर के साथ काम करेगा। –

-1

Enum डिफ़ॉल्ट रूप से है अपने first value रूप default value

+3

फिर से, यह मेरी समस्या का समाधान कैसे करता है? (और यह तकनीकी रूप से सही भी नहीं है, मुझे नहीं लगता) – fearofawhackplanet

+2

-1: क्षमा करें, लेकिन प्रत्येक enum के लिए डिफ़ॉल्ट मान 0 है, भले ही 0 enum के लिए एक अवैध मान है। 'Enum MyEnum {M1 = -1, M2 = 1} आज़माएं; MyEnum ई = डिफ़ॉल्ट (MyEnum); ... कंसोल। राइटलाइन ("{0}", ई); 'लिखता है' 0' –

-1

आप इसे एक सामान्य विधि बनाने के बारे में सोचा है लगता है?

public static string DoSomething<T>(Enum value) 
{ 
    if (!Enum.IsDefined(typeof(T), value)) 
    { 
     value = (T)Enum.ToObject(typeof(T), 0); 
    } 
    // ... do some other stuff 
} 

विधि के कॉलर को इस प्रकार को जानना चाहिए।

+3

'जहां टी: enum' सी # में मौजूद नहीं है। :-(यह पूरी समस्या है। –

+0

आह सच, इसे हटा दिया गया। –

+0

अभी भी 'कहां' के बिना काम करेगा। आपको यह सुनिश्चित करने के लिए प्रयास करना होगा कि आपकी कास्ट उड़ नहीं जाए। मैं चाहता था कॉलर को नया अपवाद फेंक दें यदि टी एन एन एन नहीं है। –

5

मैं सच में यकीन है कि आप यहाँ करने के लिए कोशिश कर रहे हैं क्या नहीं कर रहा हूँ, लेकिन 'डिफ़ॉल्ट' लाइन जो संकलन करता है के एक संस्करण यह है:

value = (Enum)Enum.GetValues(value.GetType()).GetValue(0); 

या, यहां तक ​​कि क्लीनर (पंजा से, में टिप्पणियां, धन्यवाद):

value = (Enum) Enum.ToObject(value.GetType(), 0); 

यह दूसरा संस्करण केवल ठीक से काम करता है अगर आपको पता है कि एनम के पहले तत्व में शून्य का मान है।

+0

या मूल्य = (एनम) Enum.ToObject (value.GetType(), 0); –

+0

@paw क्या होगा यदि आप ' इसका उपयोग कर रहे हैं: 'enum foo {a = 1, b = 2}'? +1 हालांकि विल, यह बहुत मजबूत दिखता है –

+0

@Paw: सं। 0 सभी enums के लिए परिभाषित मान नहीं है। –

2

आप वास्तव में क्या Paw is suggesting कर सकता है, यहां तक ​​कि एक सामान्य बाधा के साथ, आप अपने ही वर्ग के लिए इस विधि को स्थानांतरित कर सकता है:

public abstract class Helper<T> 
{ 
    public static string DoSomething<TEnum>(TEnum value) where TEnum: struct, T 
    { 
     if (!Enum.IsDefined(typeof(TEnum), value)) 
     { 
      value = default(TEnum); 
     } 

     // ... do some other stuff 

     // just to get code to compile 
     return value.ToString(); 
    } 
} 

public class EnumHelper : Helper<Enum> { } 

तब आप क्या करेंगे, उदाहरण के लिए:

MyEnum x = MyEnum.SomeValue; 
MyEnum y = (MyEnum)100; // Let's say this is undefined. 

EnumHelper.DoSomething(x); // generic type of MyEnum can be inferred 
EnumHelper.DoSomething(y); // same here 

जैसा कि कोनराड रुडॉल्फ एक टिप्पणी में बताते हैं, उपरोक्त कोड में default(TEnum) 0 का मूल्यांकन करेगा, भले ही TEnum प्रकार के लिए 0 के लिए मान परिभाषित किया गया हो या नहीं। यदि आप जो चाहते हैं वह नहीं है, Will's answer निश्चित रूप से परिभाषित मान ((TEnum)Enum.GetValues(typeof(TEnum)).GetValue(0)) प्राप्त करने का सबसे आसान तरीका प्रदान करता है।

दूसरी ओर, यदि आप चरम को यह लेते हैं, और परिणाम कैश करने के लिए इतना है कि आप इसे कभी भी बॉक्स की जरूरत नहीं है चाहता हूँ, आप ऐसा कर सकता है:

public abstract class Helper<T> 
{ 
    static Dictionary<Type, T> s_defaults = new Dictionary<Type, T>(); 

    public static string DoSomething<TEnum>(TEnum value) where TEnum: struct, T 
    { 
     if (!Enum.IsDefined(typeof(TEnum), value)) 
     { 
      value = GetDefault<TEnum>(); 
     } 

     // ... do some other stuff 

     // just to get code to compile 
     return value.ToString(); 
    } 

    public static TEnum GetDefault<TEnum>() where TEnum : struct, T 
    { 
     T definedDefault; 
     if (!s_defaults.TryGetValue(typeof(TEnum), out definedDefault)) 
     { 
      // This is the only time you'll have to box the defined default. 
      definedDefault = (T)Enum.GetValues(typeof(TEnum)).GetValue(0); 
      s_defaults[typeof(TEnum)] = definedDefault; 
     } 

     // Every subsequent call to GetDefault on the same TEnum type 
     // will unbox the same object. 
     return (TEnum)definedDefault; 
    } 
} 
+0

आपका कोड मेरे लिए संकलित नहीं करता है (मोनो सी #)। –

+0

@ कोनराड: वह * हो सकता है क्योंकि मेरे पास एक टाइपो था ('TEnumvalue'-no space)। इसके अलावा मैंने वापसी मूल्य भी शामिल नहीं किया था। मुझे यह जानकर उत्सुकता होगी कि क्या यह मोनो के लिए संकलित है कि अब मैंने उदाहरण अपडेट किया है। –

+0

मैं पहले से ही इसे ठीक कर दूंगा, मदद नहीं की। अजीब बात यह है कि अब यह संकलित करता है (+1, सुरुचिपूर्ण हैक!) - लेकिन यह अन्य समाधानों के समान समस्या है, अर्थात् 'डिफ़ॉल्ट' वास्तव में '0' देता है जो वास्तविक enum में एक अनिर्धारित मान हो सकता है और इस प्रकार यह नहीं है सही परिणाम अतिरिक्त समस्या है कि आपका समाधान अब एक्सटेंशन विधि के रूप में काम नहीं करता है। –

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