2009-08-25 9 views
19

मैंअंकन के लिए उपयोगकर्ता मित्रतापूर्ण नाम कैसे हैं?

Enum Complexity 
{ 
    NotSoComplex, 
    LittleComplex, 
    Complex, 
    VeryComplex 
} 

की तरह एक गणना है और मैं एक ड्रॉपडाउन सूची में इसका उपयोग करना चाहते हैं, लेकिन सूची में इस तरह के कैमल नाम देखने के लिए नहीं करना चाहते हैं (उपयोगकर्ताओं के लिए वास्तव में अजीब लग रहा है)। इसके बजाय मैं सामान्य शब्दों में है, ऐसा नहीं है जटिल लिटिल जटिल (आदि)

भी तरह चाहते हैं, अपने आवेदन बहु लैंग और मैं उन तार स्थानीय प्रदर्शित करने के लिए सक्षम होने के लिए चाहते हैं, और मैं एक का उपयोग करें सहायक, अनुवादहेल्पर (स्ट्रिंग स्ट्रिड) जो मुझे स्ट्रिंग आईडी के लिए स्थानीय संस्करण प्रदान करता है।

मैं एक काम कर समाधान है, लेकिन बहुत ही सुंदर नहीं: मैं एक सदस्य जटिलता और ToString() ओवरराइट, नीचे (सरलीकृत कोड) की तरह

public class ComplexityHelper 
{ 
    public ComplexityHelper(Complexity c, string desc) 
    { m_complex = c; m_desc=desc; } 

    public Complexity Complexity { get { ... } set {...} } 
    public override ToString() { return m_desc; } 

    //Then a static field like this 

    private static List<Complexity> m_cxList = null; 

    // and method that returns the status lists to bind to DataSource of lists 
    public static List<ComplexityHelper> GetComplexities() 
    { 
     if (m_cxList == null) 
     { 
      string[] list = TranslationHelper.GetTranslation("item_Complexities").Split(','); 
      Array listVal = Enum.GetValues(typeof(Complexities)); 
      if (list.Length != listVal.Length) 
       throw new Exception("Invalid Complexities translations (item_Complexities)"); 
      m_cxList = new List<Complexity>(); 
      for (int i = 0; i < list.Length; i++) 
      { 
      Complexity cx = (ComplexitylistVal.GetValue(i); 
      ComplexityHelper ch = new ComplexityHelper(cx, list[i]); 
      m_cxList.Add(ch); 
      } 
     } 
     return m_cxList; 
    } 
} 

जबकि व्यावहारिक के साथ enum के लिए एक सहायक वर्ग बनाने के लिए, , मैं इससे खुश नहीं हूं, क्योंकि मुझे इसे विभिन्न enums के लिए समान रूप से कोड करना होगा, मुझे पिकलिस्ट में उपयोग करने की आवश्यकता है।

क्या किसी के पास एक सरल या अधिक सामान्य समाधान के लिए कोई सुझाव है?

धन्यवाद Bogdan

+0

देखें

उत्तर

1

आप सभी सभी प्रश्नों के उत्तर के लिए धन्यवाद के ToString के लिए किसी भी त्रुटि होने पर ऊंट-केस विभाजन विधि

  • का प्रयोग करेंगे। अंत में मैंने रेक्स एम और एड्रियनबैंक से एक संयोजन का उपयोग किया, और कॉम्बोबॉक्स को बाध्यकारी को सरल बनाने के लिए अपने स्वयं के सुधार जोड़े।

    परिवर्तनों की आवश्यकता थी क्योंकि, कोड पर काम करते समय, मुझे एहसास हुआ कि कभी-कभी मुझे कॉम्बो से एक गणना आइटम को बाहर करने में सक्षम होना चाहिए। ईजी।

    1. : सभी (फिल्टर में) को दिखाने के लिए और अन्य समय

      यहाँ मैं क्या किया है -

      Enum Complexity 
      { 
          // this will be used in filters, 
          // but not in module where I have to assign Complexity to a field 
          AllComplexities, 
          NotSoComplex, 
          LittleComplex, 
          Complex, 
          VeryComplex 
      } 
      

      तो कभी कभी मैं picklist सभी लेकिन AllComplexities (मॉड्यूल संपादित ऐड में) दिखाना चाहते हैं मैंने एक एक्सटेंशन विधि बनाई है, जो वर्णन विशेषता का उपयोग स्थानीयकरण लुकअप कुंजी के रूप में करती है। यदि वर्णन विशेषता गुम है, तो मैं लुकअप स्थानीयकरण कुंजी को EnumName_ EnumValue के रूप में बना देता हूं। अंत में, यदि अनुवाद गुम है तो मैं एड्रियनबैंक द्वारा दिखाए गए अलग शब्दों के लिए ऊंट के आधार पर enum नाम को विभाजित करता हूं। बीटीडब्ल्यू, ट्रांसलेशनहेल्पर संसाधन के आसपास एक रैपर है Mgr.GetString (...)

    पूर्ण कोड नीचे

    public static string GetDescription(this System.Enum value) 
    { 
        string enumID = string.Empty; 
        string enumDesc = string.Empty; 
        try 
        {   
         // try to lookup Description attribute 
         FieldInfo field = value.GetType().GetField(value.ToString()); 
         object[] attribs = field.GetCustomAttributes(typeof(DescriptionAttribute), true); 
         if (attribs.Length > 0) 
         { 
          enumID = ((DescriptionAttribute)attribs[0]).Description; 
          enumDesc = TranslationHelper.GetTranslation(enumID); 
         } 
         if (string.IsNullOrEmpty(enumID) || TranslationHelper.IsTranslationMissing(enumDesc)) 
         { 
          // try to lookup translation from EnumName_EnumValue 
          string[] enumName = value.GetType().ToString().Split('.'); 
          enumID = string.Format("{0}_{1}", enumName[enumName.Length - 1], value.ToString()); 
          enumDesc = TranslationHelper.GetTranslation(enumID); 
          if (TranslationHelper.IsTranslationMissing(enumDesc)) 
           enumDesc = string.Empty; 
         } 
    
         // try to format CamelCase to proper names 
         if (string.IsNullOrEmpty(enumDesc)) 
         { 
          Regex capitalLetterMatch = new Regex("\\B[A-Z]", RegexOptions.Compiled); 
          enumDesc = capitalLetterMatch.Replace(value.ToString(), " $&"); 
         } 
        } 
        catch (Exception) 
        { 
         // if any error, fallback to string value 
         enumDesc = value.ToString(); 
        } 
    
        return enumDesc; 
    } 
    

    दिखाया गया है मैं Enum है, जो तब मैं एक बनाया डेटास्रोत

    public class LocalizableEnum 
    { 
        /// <summary> 
        /// Column names exposed by LocalizableEnum 
        /// </summary> 
        public class ColumnNames 
        { 
         public const string ID = "EnumValue"; 
         public const string EntityValue = "EnumDescription"; 
        } 
    } 
    
    public class LocalizableEnum<T> 
    { 
    
        private T m_ItemVal; 
        private string m_ItemDesc; 
    
        public LocalizableEnum(T id) 
        { 
         System.Enum idEnum = id as System.Enum; 
         if (idEnum == null) 
          throw new ArgumentException(string.Format("Type {0} is not enum", id.ToString())); 
         else 
         { 
          m_ItemVal = id; 
          m_ItemDesc = idEnum.GetDescription(); 
         } 
        } 
    
        public override string ToString() 
        { 
         return m_ItemDesc; 
        } 
    
        public T EnumValue 
        { 
         get { return m_ID; } 
        } 
    
        public string EnumDescription 
        { 
         get { return ToString(); } 
        } 
    
    } 
    

    को आसानी से enum बाध्य करने के लिए अनुमति देने के आधार पर एक सामान्य सहायक श्रेणी का निर्माण जेनेरिक स्थिर विधि जो एक सूची देता है>,

    public static List<LocalizableEnum<T>> GetEnumList<T>(object excludeMember) 
    { 
        List<LocalizableEnum<T>> list =null; 
        Array listVal = System.Enum.GetValues(typeof(T)); 
        if (listVal.Length>0) 
        { 
         string excludedValStr = string.Empty; 
         if (excludeMember != null) 
          excludedValStr = ((T)excludeMember).ToString(); 
    
         list = new List<LocalizableEnum<T>>(); 
         for (int i = 0; i < listVal.Length; i++) 
         { 
          T currentVal = (T)listVal.GetValue(i); 
          if (excludedValStr != currentVal.ToString()) 
          { 
           System.Enum enumVal = currentVal as System.Enum; 
           LocalizableEnum<T> enumMember = new LocalizableEnum<T>(currentVal); 
           list.Add(enumMember); 
          } 
         } 
        } 
        return list; 
    } 
    

    और एक आवरण सभी सदस्यों

    public static List<LocalizableEnum<T>> GetEnumList<T>() 
    { 
         return GetEnumList<T>(null); 
    } 
    

    अब साथ सूची वापस जाने के लिए की सभी चीजों को एक साथ रखा है और वास्तविक कॉम्बो करने के लिए बाध्य:

    // in module where we want to show items with all complexities 
    // or just filter on one complexity 
    
    comboComplexity.DisplayMember = LocalizableEnum.ColumnNames.EnumValue; 
    comboComplexity.ValueMember = LocalizableEnum.ColumnNames.EnumDescription; 
    comboComplexity.DataSource = EnumHelper.GetEnumList<Complexity>(); 
    comboComplexity.SelectedValue = Complexity.AllComplexities; 
    
    // .... 
    // and here in edit module where we don't want to see "All Complexities" 
    comboComplexity.DisplayMember = LocalizableEnum.ColumnNames.EnumValue; 
    comboComplexity.ValueMember = LocalizableEnum.ColumnNames.EnumDescription; 
    comboComplexity.DataSource = EnumHelper.GetEnumList<Complexity>(Complexity.AllComplexities); 
    comboComplexity.SelectedValue = Complexity.VeryComplex; // set default value 
    

    चयनित को पढ़ने के लिए मूल्य और उपयोग यह है, मैं के रूप में नीचे दिए गए कोड का उपयोग

    Complexity selComplexity = (Complexity)comboComplexity.SelectedValue; 
    
  • 60

    बेसिक अनुकूल नाम

    उपयोग Description attribute: *

    enum MyEnum 
    { 
        [Description("This is black")] 
        Black, 
        [Description("This is white")] 
        White 
    } 
    

    और enums के लिए एक उपयोगी विस्तार विधि:

    public static string GetDescription(this Enum value) 
    { 
        FieldInfo field = value.GetType().GetField(value.ToString()); 
        object[] attribs = field.GetCustomAttributes(typeof(DescriptionAttribute), true); 
        if(attribs.Length > 0) 
        { 
         return ((DescriptionAttribute)attribs[0]).Description; 
        } 
        return string.Empty; 
    } 
    

    तो तरह उपयोग किया:

    MyEnum val = MyEnum.Black; 
    Console.WriteLine(val.GetDescription()); //writes "This is black" 
    

    (ध्यान दें कि यह वास्तव में थोड़ा झंडे के लिए काम नहीं करता है ...)

    स्थानीयकरण

    के लिए वहाँ के लिए .NET में एक अच्छी तरह से स्थापित पैटर्न है स्ट्रिंग मान प्रति कई भाषाओं से निपटने - एक resource file का उपयोग, और विस्तार विधि का विस्तार संसाधन फ़ाइल से पढ़ने का:

    public static string GetDescription(this Enum value) 
    { 
        FieldInfo field = value.GetType().GetField(value.ToString()); 
        object[] attribs = field.GetCustomAttributes(typeof(DescriptionAttribute), true)); 
        if(attribs.Length > 0) 
        { 
         string message = ((DescriptionAttribute)attribs[0]).Description; 
         return resourceMgr.GetString(message, CultureInfo.CurrentCulture); 
        } 
        return string.Empty; 
    } 
    

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

    यह सब लाना एक साथ

    इस एक DropDownList करने के लिए बाध्य करने के लिए, हम शायद हमारे नियंत्रण में वास्तविक enum मान ट्रैक और दृश्य चीनी में अनुवाद किया, दोस्ताना नाम को सीमित करना चाहते।हम एक गुमनाम प्रकार और सूची पर DataField गुण का उपयोग करके ऐसा कर सकते हैं:

    • पहले हम फोन Enum.GetValues(typeof(MyEnum)) है, जो हमें एक शिथिल टाइप Array हो जाता है:

      <asp:DropDownList ID="myDDL" 
              DataTextField="Description" 
              DataValueField="Value" /> 
      
      myDDL.DataSource = Enum.GetValues(typeof(MyEnum)).OfType<MyEnum>().Select(
          val => new { Description = val.GetDescription(), Value = val.ToString() }); 
      
      myDDL.DataBind(); 
      

      के नीचे है कि डेटा स्रोत लाइन तोड़ने चलो

    • अगला मूल्यों की हम OfType<MyEnum>() जो एक IEnumerable<MyEnum>
    • फिर हम Select() फोन और एक लैम्ब्डा है कि एक नए परियोजनाओं प्रदान करने के लिए सरणी धर्मान्तरित फोन दो फ़ील्ड, विवरण और मूल्य के साथ वस्तु।

    डाटाटेक्स्टफिल्ड और डेटावेल्यूफ़ील्ड गुणों का मूल्यांकन डाटाबेस-टाइम पर प्रतिबिंबित किया जाता है, इसलिए वे मिलान नामों के साथ डेटाइटम पर फ़ील्ड की खोज करेंगे।

    - मुख्य लेख में ध्यान दें, लेखक अपने स्वयं के DescriptionAttribute वर्ग जो अनावश्यक है, के रूप में पहले से ही नेट के मानक पुस्तकालयों में मौजूद लिखा था। -

    +5

    स्थानीयकरण के लिए, आप वर्णन विशेषताओं को छोड़ कर सकते हैं और बस "MyEnum.Blac का उपयोग के "और" MyEnum.White "संसाधन नाम के रूप में। – stevemegson

    +0

    @stevemegson जो निश्चित रूप से काम करेगा! मैं एक बड़ी SoC/SRP शुद्धतावादी हालांकि हूँ, और मेरे लिए डबल उद्देश्य चेतावनी की घंटी बंद :) –

    +0

    हाय कुंजी सेट दोनों एक कार्यक्रम संबंधी मूल्य और एक बहु भाषा संसाधन के रूप में enum, मैं पूरा करने के लिए चाहते हैं क्या उपयोग करने के लिए है एक बाध्यकारी comboComplexity.DataSource = Enum.GetValues ​​(टाइपऑफ (जटिलता)); लेकिन मैं अभी भी इस का उपयोग कर गणना मूल्यों के नाम कॉम्बो में मिलता है, और नहीं उनके विवरण इसके अलावा, मैं toString() के लिए GetDescription नाम बदला, उम्मीद है कि कॉम्बो enum नाम के लिए इस्तेमाल करेगा कि है, लेकिन कोई किस्मत कोई सुझाव? धन्यवाद – bzamfir

    1

    मैं निम्नलिखित वर्ग का उपयोग

    public class EnumUtils 
        { 
        /// <summary> 
        ///  Reads and returns the value of the Description Attribute of an enumeration value. 
        /// </summary> 
        /// <param name="value">The enumeration value whose Description attribute you wish to have returned.</param> 
        /// <returns>The string value portion of the Description attribute.</returns> 
        public static string StringValueOf(Enum value) 
        { 
         FieldInfo fi = value.GetType().GetField(value.ToString()); 
         DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false); 
         if (attributes.Length > 0) 
         { 
          return attributes[0].Description; 
         } 
         else 
         { 
          return value.ToString(); 
         } 
        } 
    
        /// <summary> 
        ///  Returns the Enumeration value that has a given Description attribute. 
        /// </summary> 
        /// <param name="value">The Description attribute value.</param> 
        /// <param name="enumType">The type of enumeration in which to search.</param> 
        /// <returns>The enumeration value that matches the Description value provided.</returns> 
        /// <exception cref="ArgumentException">Thrown when the specified Description value is not found with in the provided Enumeration Type.</exception> 
        public static object EnumValueOf(string value, Type enumType) 
        { 
         string[] names = Enum.GetNames(enumType); 
         foreach (string name in names) 
         { 
          if (StringValueOf((Enum)Enum.Parse(enumType, name)).Equals(value)) 
          { 
           return Enum.Parse(enumType, name); 
          } 
         } 
    
         throw new ArgumentException("The string is not a description or value of the specified enum."); 
        } 
    

    कौन सा एक विशेषता वर्णन

    public enum PuppyType 
    { 
        [Description("Cute Puppy")] 
        CutePuppy = 0, 
        [Description("Silly Puppy")] 
        SillyPuppy 
    } 
    
    4

    अन्य उत्तर में के रूप में विशेषताओं का उपयोग जाने के लिए एक अच्छा तरीका है कहा जाता है पढ़ता है, लेकिन अगर आप बस enum के मानों से पाठ का उपयोग करना चाहते हैं, निम्नलिखित कोड मूल्य के ऊंट-आवरण के आधार पर विभाजित होगा:

    public static string GetDescriptionOf(Enum enumType) 
    { 
        Regex capitalLetterMatch = new Regex("\\B[A-Z]", RegexOptions.Compiled); 
        return capitalLetterMatch.Replace(enumType.ToString(), " $&"); 
    } 
    

    कॉलिंग GetDescriptionOf(Complexity.NotSoComplex)Not So Complex वापस आ जाएगी। इसका उपयोग किसी भी एनम वैल्यू के साथ किया जा सकता है।

    यह अधिक उपयोगी बनाने के लिए, आप इसे एक विस्तार विधि बना सकता है:

    public static string ToFriendlyString(this Enum enumType) 
    { 
        Regex capitalLetterMatch = new Regex("\\B[A-Z]", RegexOptions.Compiled); 
        return capitalLetterMatch.Replace(enumType.ToString(), " $&"); 
    } 
    

    अब आप कैलोरी Complexity.NotSoComplex.ToFriendlyString() का उपयोग कर Not So Complex वापस जाने के लिए यह कहते हैं।


    संपादित: सिर्फ देखा है कि आपके प्रश्न में आपका उल्लेख है कि आप पाठ स्थानीय बनाना की जरूरत है। उस स्थिति में, मैं स्थानीय मान को देखने के लिए एक कुंजी रखने के लिए एक विशेषता का उपयोग करता हूं, लेकिन स्थानीय पाठ को नहीं मिला तो अंतिम उपाय के रूप में अनुकूल स्ट्रिंग विधि के लिए डिफ़ॉल्ट।आप इस तरह आप enums निर्धारित करना होगा:

    enum Complexity 
    { 
        [LocalisedEnum("Complexity.NotSoComplex")] 
        NotSoComplex, 
        [LocalisedEnum("Complexity.LittleComplex")] 
        LittleComplex, 
        [LocalisedEnum("Complexity.Complex")] 
        Complex, 
        [LocalisedEnum("Complexity.VeryComplex")] 
        VeryComplex 
    } 
    

    आप भी इस कोड की आवश्यकता होगी:

    [AttributeUsage(AttributeTargets.Field, AllowMultiple=false, Inherited=true)] 
    public class LocalisedEnum : Attribute 
    { 
        public string LocalisationKey{get;set;} 
    
        public LocalisedEnum(string localisationKey) 
        { 
         LocalisationKey = localisationKey; 
        } 
    } 
    
    public static class LocalisedEnumExtensions 
    { 
        public static string ToLocalisedString(this Enum enumType) 
        { 
         // default value is the ToString(); 
         string description = enumType.ToString(); 
    
         try 
         { 
          bool done = false; 
    
          MemberInfo[] memberInfo = enumType.GetType().GetMember(enumType.ToString()); 
    
          if (memberInfo != null && memberInfo.Length > 0) 
          { 
           object[] attributes = memberInfo[0].GetCustomAttributes(typeof(LocalisedEnum), false); 
    
           if (attributes != null && attributes.Length > 0) 
           { 
            LocalisedEnum descriptionAttribute = attributes[0] as LocalisedEnum; 
    
            if (description != null && descriptionAttribute != null) 
            { 
             string desc = TranslationHelper.GetTranslation(descriptionAttribute.LocalisationKey); 
    
             if (desc != null) 
             { 
              description = desc; 
              done = true; 
             } 
            } 
           } 
          } 
    
          if (!done) 
          { 
           Regex capitalLetterMatch = new Regex("\\B[A-Z]", RegexOptions.Compiled); 
           description = capitalLetterMatch.Replace(enumType.ToString(), " $&"); 
          } 
         } 
         catch 
         { 
          description = enumType.ToString(); 
         } 
    
         return description; 
        } 
    } 
    

    स्थानीयकृत विवरणों के लिए, आप तो कहेंगे:

    Complexity.NotSoComplex.ToLocalisedString() 
    

    यह कई है फॉलबैक मामले:

    • अगर एनयू मीटर एक LocalisedEnum विशेषता परिभाषित किया गया है, यह अगर enum एक LocalisedEnum विशेषता परिभाषित है, लेकिन कोई स्थानीयकृत लेख पाया जाता है, यह ऊंट-केस विभाजन विधि
    • यदि का उपयोग करने में चूक अनुवादित पाठ
    • को देखने के लिए कुंजी का उपयोग करेगा enum एक LocalisedEnum विशेषता परिभाषित नहीं है, यह है, यह चूक enum मूल्य
    +0

    हाय जवाब के लिए धन्यवाद। मैं अपने सुझाव की कोशिश की, और कॉम्बो बाध्य करने के लिए इस तरह comboComplexity.DataSource = Enum.GetValues ​​(typeof (जटिलता)) कोड के साथ Enum की कोशिश की, लेकिन इसने सूची को केवल डिफ़ॉल्ट enum नामों को प्रदर्शित करने के लिए बनाया है मैंने टोलोकलाइज्डस्ट्रिंग() को ToString() में भी नाम दिया है (यह जानकर कि यह वास्तव में कॉम्बो द्वारा बुलाया जाता है) लेकिन अभी भी काम नहीं किया है। कोई सुझाव? मुझे इस तरह की एक सरल बाध्यकारी पसंद है, क्योंकि 20+ मूल्यों के साथ एक enum के साथ, सभी मूल्यों को एक-एक करके जोड़ना दर्द होगा धन्यवाद – bzamfir

    +0

    ToLocalizedString() को ToString() में नामित करके, आपने ToString() को ओवरराइड नहीं किया है enum की विधि। इसके बजाए, आपने एनम के पहले से मौजूद ToString() विधि के समान नाम के साथ एक एक्सटेंशन विधि बनाई है।कॉलिंग ToString() मौजूदा विधि को कॉल करेगा, न कि एक्सटेंशन विधि। आपको स्ट्रिंग के उस सेट पर प्रत्येक एनम वैल्यू और डाटाबेस के लिए स्थानीय तारों को प्राप्त करना होगा। – adrianbanks

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