2009-10-16 16 views
7

मैं में के रूप में एक enum करना चाहते हैं:enums के लिए तार होना संभव है?

enum FilterType 
{ 
    Rigid = "Rigid", 
    SoftGlow = "Soft/Glow", 
    Ghost = "Ghost", 
} 

यह कैसे प्राप्त करने के लिए? क्या ऐसा करने के लिए इससे अच्छा तरीका है? इसका उपयोग किसी ऑब्जेक्ट के उदाहरण के लिए किया जाएगा जहां इसे धारावाहिक/deserialized किया जा रहा है। यह एक ड्रॉपडाउन सूची भी तैयार करेगा।

उत्तर

11
using System.ComponentModel; 
enum FilterType 
{ 
    [Description("Rigid")] 
    Rigid, 
    [Description("Soft/Glow")] 
    SoftGlow, 
    [Description("Ghost")] 
    Ghost , 
} 

आप इस

public static String GetEnumerationDescription(Enum e) 
{ 
    Type type = e.GetType(); 
    FieldInfo fieldInfo = type.GetField(e.ToString()); 
    DescriptionAttribute[] da = (DescriptionAttribute[])(fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false)); 
    if (da.Length > 0) 
    { 
    return da[0].Description; 
    } 
    return e.ToString(); 
} 
की तरह मूल्य बाहर निकल सकते हैं
+4

अच्छा दृष्टिकोण। आप इसे सभी enums के लिए एक विस्तार विधि के रूप में भी हो सकता है। –

+1

धन्यवाद .. मेरे पास कुछ स्थिर विधियां हैं जिनका उपयोग मैं अपने वर्तमान प्रोजेक्ट पर इस तरह के enums से निपटने के लिए करता हूं।मैंने कभी विस्तार विधि का उपयोग करने के बारे में सोचा नहीं। मुझे यह कोशिश करना है कि –

+0

यह एक अच्छा अभ्यास है ... इसे एक और विशेषता परिभाषित करना .... [System.Xml.Serialization.XmlEnum ("कठोर")] पर ... [विवरण (" कठोर ")] कठोर, ... आदि। –

1

यह संभव नहीं है। सी # केवल अभिन्न एनम प्रकार (int, लघु, लंबा, आदि) की अनुमति देता है। आप या तो हल्के "enum-like" वर्ग बना सकते हैं या स्थिर स्थिरांक का उपयोग कर सकते हैं।

static class FilterTypes 
{ 
    public const string Rigid = "Rigid"; 
    // ... 
} 

// or ... 

class FilterType 
{ 
    static readonly FilterType RigidFilterType = new FilterType("Rigid"); 

    string name; 

    FilterType(string name) // private constructor 
    { 
     this.name = name; 
    } 

    public static FilterType Rigid 
    { 
     get { return FilterType.RigidFilterType; } 
    } 

    // ... 
} 
+0

+1 इस तरह से व्यवहार करने के लिए कक्षा या संरचना को लागू करने के लिए +1। –

0

नहीं, यह संभव नहीं है।

एक enum लिए मंजूरी दे दी प्रकार बाइट, sbyte, लघु, ushort, पूर्णांक, uint, लंबे, या Ulong हैं।

हालांकि, अगर आप Enum श्रेणी के साथ एक enum की घोषणा की नाम को पुनः प्राप्त कर सकते हैं:

string name = Enum.GetName(typeof(FilterType), FilterType.Rigid); 

यदि यह एक वर्ग पराक्रम में एकत्र स्ट्रिंग स्थिरांक का एक संग्रह आप के लिए काम नहीं करता।

1

Enums हमेशा एक पूर्णांक मान से जुड़े होते हैं। तो नहीं। आप स्ट्रिंग मान प्राप्त करने के लिए FilterType.Rigid.ToString() कर सकते हैं हालांकि इसे सीधे स्थानीयकृत नहीं किया जा सकता है।

9

नहीं है, लेकिन अगर आप गुंजाइश करना चाहते हैं "स्थिरांक" तार और उन्हें एक enum की तरह इस्तेमाल करते हैं, यहाँ मैं क्या कर रहा है:

public static class FilterType 
{ 
    public const string Rigid = "Rigid"; 
    public const string SoftGlow = "Soft/Glow"; 
    public const string Ghost ="Ghost"; 
} 
+0

इस तरह मैंने अतीत में भी ऐसा किया है, अधिकांश उद्देश्यों के लिए अच्छी तरह से काम करता है। – Chris

+1

इस दृष्टिकोण का नकारात्मक पक्ष यह है कि मैं नहीं देख सकता कि आप स्वचालित रूप से ड्रॉप डाउन कैसे बना सकते हैं। एक छोटे से काम के साथ आप कम से कम एक enum के मूल्यों को फिर से शुरू करने का विकल्प है। –

+0

@ माइकल: आप शायद कुछ (गन्दा) प्रतिबिंब कोड के साथ पुनरावृत्त कर सकते हैं। –

1

आप इस

FilterType myType = FilterType.Rigid; 
String strType = myType.ToString(); 
की तरह एक स्ट्रिंग के रूप Enum नाम प्राप्त कर सकते हैं

हालांकि, आप ऊंट केस/हंगेरियन नोटेशन से फंस सकते हैं, लेकिन आप आसानी से इस तरह की विधि का उपयोग करके अधिक उपयोगकर्ता के अनुकूल स्ट्रिंग में परिवर्तित कर सकते हैं (सबसे सुंदर समाधान नहीं, मैं इसे अनुकूलित करने के लिए इनपुट के लिए आभारी हूं) :

Public Shared Function NormalizeCamelCase(ByVal str As String) As String 

    If String.IsNullOrEmpty(str) Then 
     Return String.Empty 
    End If 

    Dim i As Integer = 0 
    Dim upperCount As Integer = 0 
    Dim otherCount As Integer = 0 
    Dim normalizedString As String = str 

    While i < normalizedString.Length 

     If Char.IsUpper(normalizedString, i) Then 
      ''Current char is Upper Case 
      upperCount += 1 
      If i > 0 AndAlso Not normalizedString(i - 1).Equals(" "c) Then 
       ''Current char is not first and preceding char is not a space 
       ''...insert a space, move to next char 
       normalizedString = normalizedString.Insert(i, " ") 
       i += 1 
      End If 
     ElseIf Not Char.IsLetter(normalizedString, i) Then 
      otherCount += 1 
     End If 

     ''Move to next char 
     i += 1 

    End While 

    If upperCount + otherCount = str.Length Then 
     ''String is in all caps, return original string 
     Return str 
    Else 
     Return normalizedString 
    End If 

End Function 

हैं कि अभी भी बहुत पर्याप्त नहीं है, तो आप देखने के लिए में कस्टम विशेषताओं जो प्रतिबिंब का उपयोग कर प्राप्त किया जा सकता है चाहते हो सकता है, ...

1

नहीं, लेकिन आप इस तरह से धोखा कर सकते हैं:

public enum FilterType{ 
    Rigid, 
    SoftGlow, 
    Ghost 
} 

और फिर जब आप उनके strin की जरूरत जी तुम सिर्फ FilterType.Rigid.ToString कर सकते हैं को महत्व देता है()

+1

इसे इस तरह से करना (जिसे मैं भी दोषी हूं) बिना रिक्त स्थान/विशेष पात्रों के बिना उपयोगकर्ता टेक्स्ट दिखाता है (सॉफ़्टग्लो "सॉफ्ट/ग्लो" के विपरीत), जो मुझे यकीन है कि वह ऐसा करने में सक्षम होना चाहता है। – Pwninstein

0

आप मूल्यों

से अधिक एक गुण का उपयोग कर सकते
[System.ComponentModel.Description("Rigid")] 

उदाहरण:

enum FilterType 
{ 
    [System.ComponentModel.Description("Rigid")] 
    Rigid, 
    [System.ComponentModel.Description("Soft/Glow")] 
    SoftGlow, 
    [System.ComponentModel.Description("Ghost")] 
    Ghost 
} 

और उपयोग का विवरण प्राप्त करने के लिए प्रतिबिंब।

Enum विस्तार विधि:

public static string GetDescription(this Enum en) 
    { 
     var type = en.GetType(); 
     var memInfo = type.GetMember(en.ToString()); 

     if (memInfo != null && memInfo.Length > 0) 
     { 
      var attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false); 
      if (attrs != null && attrs.Length > 0) 
       return ((DescriptionAttribute)attrs[0]).Description; 
     } 
     return en.ToString(); 
    } 

यह उपयोग:

FilterType = FilterType.Rigid; 
      string description= result.GetDescription(); 
1

System.ComponentModel नाम स्थान में एक वर्ग DescriptionAttribute कि अच्छी तरह से यहाँ काम करता है।

enum FilterType 
{ 
    Rigid, 
    [Description("Soft/Glow")] 
    SoftGlow, 
    Ghost, 
} 

तब वर्णन मिलता है और ToString()

var descriptionAttribute = Value.GetType() 
.GetField(Value.ToString()) 
.GetCustomAttributes(typeof(DescriptionAttribute), false) 
.OfType <DescriptionAttribute>() 
.FirstOrDefault()??new DescriptionAttribute(Value.ToString()); 
2

आप विस्तार के तरीकों के साथ सहज हैं, तो आप आसानी से आप क्या कर रहे हैं कर सकते हैं के लिए खत्म हो विफल बाद:

//Can return string constants, the results of a Database call, 
//or anything else you need to do to get the correct value 
//(for localization, for example) 
public static string EnumValue(this MyEnum e) { 
    switch (e) { 
     case MyEnum.First: 
      return "First Friendly Value"; 
     case MyEnum.Second: 
      return "Second Friendly Value"; 
     case MyEnum.Third: 
      return "Third Friendly Value"; 
    } 
    return "Horrible Failure!!"; 
} 

इस तरह से आप कर सकते हैं:

Private MyEnum value = MyEnum.First; 
Console.WriteLine(value.EnumValue()); 
0

शॉन बोवे के उदाहरण की तर्ज पर आप एन # 3 में एनम के लिए एक विस्तार विधि के साथ भी ऐसा कर सकते हैं (मैं नहीं आया और नहीं कर सकता, मेरे जीवन के लिए, याद रखें कि मैंने कहाँ किया था)।

एक गुण बनाएँ:

public class DisplayTextAttribute : Attribute { 
    public DisplayTextAttribute(String text) { 
    Text = text; 
    } 
    public string Text { get; set; } 
} 

एक विस्तार बनाएँ:

public static class EnumHelpers { 
    public static string GetDisplayText(this Enum enumValue) { 
    var type = enumValue.GetType(); 
    MemberInfo[] memberInfo = type.GetMember(enumValue.ToString()); 

    if (memberInfo == null || memberInfo.Length == 0) 
     return enumValue.ToString(); 

    object[] attributes = memberInfo[0].GetCustomAttributes(typeof(DisplayTextAttribute), false); 
    if (attributes == null || attributes.Length == 0) 
     return enumValue.ToString(); 

    return ((DisplayTextAttribute)attributes[0]).Text; 
    } 
} 

मैं इस पाया है वास्तव में साफ समाधान किया जाना है। अपने enum में निम्नलिखित जोड़ें:

enum FilterType{ 
    Rigid, 
    [DisplayText("Soft/Glow")] 
    SoftGlow, 
    Ghost 
} 

फिर आप FilterType.GetDisplayText() जो वापस को असंबद्ध enums और विशेषताओं के साथ लोगों के लिए DisplayText के लिए स्ट्रिंग खींच लेंगे यहां पहुंच सकता है।

+0

दिलचस्प दृष्टिकोण। बस सुनिश्चित करें कि आप इस कोड का उपयोग "उच्च प्रदर्शन" पथ में नहीं करते हैं, क्योंकि यह प्रतिबिंब कॉल करने के लिए काफी महंगा है। – bobbymcr

1

यह बिल्कुल संभव नहीं है। हालांकि आप इसे सरणी का उपयोग करके नकली बना सकते हैं।

पहले, बनाएं आप जिस तरह से Enum आप नियमित एक:

private static string[] regexs = new string[] 
{ 
    "[A-Za-z]", 
    "[0-9]", 
    "etc"... 
} 

तो फिर तुम पहुँच सकते हैं:

public enum Regexs 
{ 
    ALPHA = 0, 
    NUMERIC = 1, 
    etc.. 
} 

तो फिर तुम एक सरणी है कि मूल्यों enum मूल्यों के लिए इसी रखती बनाने enum मूल्य के माध्यम से आपके तार:

public void runit(Regexs myregexEnum) 
{ 
    Regex regex = new Regex(regexs [(int)myregexEnum]); 
} 
+0

मुझे नहीं लगता कि इस समाधान के पहले से ही (ढाई साल) स्वीकार्य उत्तर के खिलाफ कोई लाभ है, क्योंकि अब आप दो स्थानों को सिंक में रखना चाहते हैं यदि आप enum में कोई बदलाव करते हैं। – Oliver

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