2011-02-08 22 views
8

Posso avere un enum che funge da coppia di valori chiave.Coppia valore chiave come enum

public enum infringementCategory 
{ 
    Infringement, 
    OFN 
} 

Se seleziono Infringement dovrei ottenere "INF0001" e se seleziono OFN dovrei ottenere "INF0002"

E 'possibile?

+0

possibile duplicato del [enumerazioni C# String] (http://stackoverflow.com/questions/424366/c-sharp-string-enums) – nawfal

+0

Enum non è una buona scelta nel tuo caso, utilizzare il dizionario, invece. –

risposta

5

È possibile utilizzare decoratori al fine di associare rappresentazione di stringa con i tuoi valori enum. Controllare questa domanda: Enum ToString with user friendly strings

Sembrerà:

public enum infringementCategory 
{ 
    [Description("INF0001")] 
    Infringement, 
    [Description("INF0002")] 
    OFN 
} 

sembra più ordinata rispetto all'utilizzo di dizionario e ha bisogno di meno manutenzione.

2

è possibile memorizzare i titoli (INF0001) ... in un Dictionary<infringementCategory, string>

3

Aggiornamento:
Grazie a Oliver per aver ricordato System.Component.DescriptionAttribute. Ecco come fare:

public enum infringementCategory 
{ 
    [Description("INF0001")] 
    Infringement, 
    [Description("INF0002")] 
    OFN 
} 

public static class DescriptionExtensions 
{ 
    public static string GetDescriptionValue(this Enum value) 
    { 
     // Get the type 
     Type type = value.GetType(); 

     // Get fieldinfo for this type 
     FieldInfo fieldInfo = type.GetField(value.ToString()); 

     // Get the stringvalue attributes 
     DescriptionAttribute[] attribs = fieldInfo.GetCustomAttributes(
      typeof(DescriptionAttribute), false) as DescriptionAttribute[]; 

     // Return the first if there was a match. 
     return attribs.Length > 0 ? attribs[0].Description : null; 
    } 
} 

public class Program 
{ 
    static void Main(string[] args) 
    { 
     infringementCategory category = infringementCategory.OFN; 
     string description = category.GetDescriptionValue(); 
    } 
} 
+1

Perché utilizzare un attributo auto-scritto se si può semplicemente prendere ['DescriptionAttribute'] (http://msdn.microsoft.com/en-us/library/system.componentmodel.descriptionattribute.aspx)? – Oliver

+0

@Oliver Sono d'accordo, anche se il post del blog ha anche un metodo di estensione per ottenere i valori degli attributi –

-1

Si dispone di un numero di scelte:

  1. un dizionario come vc74 suggerito. Questo è efficiente e disaccoppia il tuo enum dalla proprietà.

  2. Un interruttore dichiarazione

  3. Se l'unica cosa che si desidera associare a ciascuna è un numero intero è possibile utilizzare:

    public enum InfringementCategory 
    { 
        Infringement = 1, 
        OFN = 2 
    } 
    

    e poi mettere (int)myEnum in String.Format per trasformarlo in una serie di la forma che vuoi

  4. un attributo

    public enum InfringementCategory 
    { 
        [InfID("INF0001")]Infringement, 
        [InfID("INF0002")]OFN 
    } 
    

    Per migliorare le prestazioni è possibile utilizzare riflessione una volta per popolare dizionario.

7

Che ne dite di queste estensioni:

public static class EnumExtension 
{ 
    /// <summary> 
    /// Gets the string of an DescriptionAttribute of an Enum. 
    /// </summary> 
    /// <param name="value">The Enum value for which the description is needed.</param> 
    /// <returns>If a DescriptionAttribute is set it return the content of it. 
    /// Otherwise just the raw name as string.</returns> 
    public static string Description(this Enum value) 
    { 
     if (value == null) 
     { 
      throw new ArgumentNullException("value"); 
     } 

     string description = value.ToString(); 
     FieldInfo fieldInfo = value.GetType().GetField(description); 
     DescriptionAttribute[] attributes = 
      (DescriptionAttribute[]) 
     fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false); 

     if (attributes != null && attributes.Length > 0) 
     { 
      description = attributes[0].Description; 
     } 

     return description; 
    } 

    /// <summary> 
    /// Creates an List with all keys and values of a given Enum class 
    /// </summary> 
    /// <typeparam name="T">Must be derived from class Enum!</typeparam> 
    /// <returns>A list of KeyValuePair&lt;Enum, string&gt; with all available 
    /// names and values of the given Enum.</returns> 
    public static IList<KeyValuePair<Enum, string>> ToList<T>() where T : struct 
    { 
     var type = typeof(T); 

     if (!type.IsEnum) 
     { 
      throw new ArgumentException("T must be an enum"); 
     } 

     return (IList<KeyValuePair<Enum, string>>) 
       Enum.GetValues(type) 
        .OfType<Enum>() 
        .Select(e => new KeyValuePair<Enum, string>(e, e.Description())) 
        .ToArray(); 
    } 

    public static T GetValueFromDescription<T>(string description) where T : struct 
    { 
     var type = typeof(T); 

     if(!type.IsEnum) 
     { 
      throw new ArgumentException("T must be an enum"); 
     } 

     foreach(var field in type.GetFields()) 
     { 
      var attribute = Attribute.GetCustomAttribute(field, 
       typeof(DescriptionAttribute)) as DescriptionAttribute; 

      if(attribute != null) 
      { 
       if(attribute.Description == description) 
       { 
        return (T)field.GetValue(null); 
       } 
      } 
      else 
      { 
       if(field.Name == description) 
       { 
        return (T)field.GetValue(null); 
       } 
      } 
     } 

     throw new ArgumentOutOfRangeException("description"); 
     // or return default(T); 
    } 
} 

Con questo in luogo si può costruito il tuo enum come questo:

public enum Foo 
{ 
    [Description("Foo - Something")] 
    Something, 
    [Description("Foo - Anything")] 
    Anything, 
} 

e ottenere la vostra lista come questa:

var list = EnumExtension.ToList<Foo>(); 
2

Vedi:

public enum InfringementCategory 
{ 
    [EnumNamedConstant(Description = "INF0001")] 
    Infringement, 

    [EnumNamedConstant(Description = "INF0002")] 
    OFN 
} 

public class Test{ 
    public void Test() 
    { 
     String result = InfringementCategory.Infringement.GetDescription(); 
    } 
} 

E qui i metodi di estensione ...

#region [ EnumNamedConstantAttribute ] 
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)] 
public class EnumNamedConstantAttribute : Attribute 
{ 
    public string Description { get; set; } 
    public string Value { get; set; } 
} 
#endregion 


#region EnumUtilities 
public static class EnumUtilities 
{ 
    #region [ + Extension Methods ] 

    #region [ GetDescription ] 

    public static string GetDescription(this Enum constant) 
    { 
     return EnumUtilities.GetEnumNamedConstantAttribute(constant).Description; 
    } 
    #endregion 

    #region [ GetStringValue ] 

    public static string GetStringValue(this Enum constant) 
    { 
     return GetEnumNamedConstantValue(constant); 
    } 
    #endregion 

    #endregion 

    #region [ + Static Methods ] 

    #region [ GetEnumerable ] 

    public static IEnumerable<EnumNamedConstantAttribute> GetEnumerable<T>() 
    { 
     T instancia = Activator.CreateInstance<T>(); 

     FieldInfo[] objInfos = instancia.GetType().GetFields(BindingFlags.Public | BindingFlags.Static); 
     foreach (FieldInfo objFileInfo in objInfos) 
     { 
      Enum constant = (Enum)objFileInfo.GetValue(objFileInfo); 
      if (objFileInfo.GetCustomAttributes(typeof(EnumNamedConstantAttribute), false).Length != 0) 
      { 
       yield return new EnumNamedConstantAttribute() 
       { 
        Description = EnumUtilities.GetEnumNamedConstantAttribute(constant).Description, 
        Value = GetEnumNamedConstantValue(constant) 
       }; 
      } 
     } 
    } 
    #endregion 

    #endregion 

    #region [ + Privates ] 

    #region [ GetEnumNamedConstantAttribute ] 
    private static EnumNamedConstantAttribute GetEnumNamedConstantAttribute(Enum constant) 
    { 
     FieldInfo[] objInfos = constant.GetType().GetFields(BindingFlags.Public | BindingFlags.Static); 
     foreach (FieldInfo objFileInfo in objInfos) 
     { 
      Enum constantItem = (Enum)objFileInfo.GetValue(objFileInfo); 
      if (constantItem.GetHashCode().Equals(constant.GetHashCode())) 
      { 
       object[] attributes = objFileInfo.GetCustomAttributes(typeof(EnumNamedConstantAttribute), false); 

       if (attributes.Length > 0) 
        return (EnumNamedConstantAttribute)attributes[0]; 
      } 
     } 
     return null; 
    } 
    #endregion 

    #region [ GetEnumNamedConstantValue ] 
    private static string GetEnumNamedConstantValue(Enum constant) 
    { 
     string sValue = (constant.GetHashCode()).ToString(); 
     EnumNamedConstantAttribute objRet = EnumUtilities.GetEnumNamedConstantAttribute(constant); 
     if (objRet != null) 
     { 
      String sAux = objRet.Value; 
      if (!String.IsNullOrEmpty(sAux)) 
       sValue = objRet.Value; 
     } 
     return sValue; 
    } 
    #endregion 

    #endregion 
} 
#endregion 
Problemi correlati