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.
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.
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.
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.
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); } }
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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With