Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Localizing enum descriptions attributes

What is the best way to localize enumeration descriptions in .net?

(See Adding descriptions to enumeration constants for enum description example)

Ideally I would like something that uses ResourceManager and resource files so it fits in with how other areas of the app are localized.

like image 1000
Ryan Avatar asked Feb 20 '09 11:02

Ryan


People also ask

How do you localize an enum?

So what we usually do for enums that need to be localized is to write an extension class that provides a method to obtain the translated name. You can just use a switch that returns strings from the usual resources. That way, you provide translated strings for enums via the resources just like you do for other strings.

What is enum description?

An enumeration type (or enum type) is a value type defined by a set of named constants of the underlying integral numeric type. To define an enumeration type, use the enum keyword and specify the names of enum members: C# Copy.

Can we assign string value to enum in C#?

You can even assign different values to each member. The enum can be of any numeric data type such as byte, sbyte, short, ushort, int, uint, long, or ulong. However, an enum cannot be a string type.


2 Answers

This is what I ended up going with, I didn't see the value in adding a custom attribute class to hold a resource key and then looking up into the resource files - why not just use the enums typename + value as a resource key?

using System; using System.Resources; using System.Reflection;  public class MyClass {   enum SomeEnum {Small,Large};    private ResourceManager _resources = new ResourceManager("MyClass.myResources",                           System.Reflection.Assembly.GetExecutingAssembly());        public string EnumDescription(Enum enumerator)   {          string rk = String.Format("{0}.{1}",enumerator.GetType(),enumerator);     string localizedDescription = _resources.GetString(rk);      if (localizedDescription == null)        {        // A localized string was not found so you can either just return        // the enums value - most likely readable and a good fallback.        return enumerator.ToString();         // Or you can return the full resourceKey which will be helpful when        // editing the resource files(e.g. MyClass+SomeEnum.Small)         // return resourceKey;        }     else        return localizedDescription;     }     void SomeRoutine()   {     // Looks in resource file for a string matching the key     // "MyClass+SomeEnum.Large"     string s1 = EnumDescription(SomeEnum.Large);          } } 
like image 86
Ryan Avatar answered Oct 08 '22 22:10

Ryan


My solution, using native decription attribute:

public class LocalizedEnumAttribute : DescriptionAttribute {     private PropertyInfo _nameProperty;     private Type _resourceType;      public LocalizedEnumAttribute(string displayNameKey)         : base(displayNameKey)     {      }      public Type NameResourceType     {         get         {             return _resourceType;         }         set         {             _resourceType = value;              _nameProperty = _resourceType.GetProperty(this.Description, BindingFlags.Static | BindingFlags.Public);         }     }      public override string Description     {         get         {             //check if nameProperty is null and return original display name value             if (_nameProperty == null)             {                 return base.Description;             }              return (string)_nameProperty.GetValue(_nameProperty.DeclaringType, null);         }     } }  public static class EnumExtender {     public static string GetLocalizedDescription(this Enum @enum)     {         if (@enum == null)             return null;          string description = @enum.ToString();          FieldInfo fieldInfo = @enum.GetType().GetField(description);         DescriptionAttribute[] attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);          if (attributes.Any())             return attributes[0].Description;          return description;     } } 

The Enum declaration

public enum MyEnum {     [LocalizedEnum("ResourceName", NameResourceType = typeof(ResourceType))]     Test = 0 } 

Then call MyEnumInstance.GetLocalizedDescription()

like image 26
nairik Avatar answered Oct 08 '22 22:10

nairik