Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Enum attribute get localization
namespace <your_namespace>
{
using System;
using System.Collections;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Threading;
/// <summary>
/// Extension for your Enum types.
/// </summary>
public static class EnumExtensions
{
/// <summary>
/// Get object custom attribute by dynamic attribute type.
/// </summary>
/// <typeparam name="T">Type of input object.</typeparam>
/// <typeparam name="TAttr">Founding custom attribute.</typeparam>
/// <param name="val">Value of object type <see cref="T"/></param>
/// <exception cref="System.ArgumentNullException">If value is null.</exception>
/// <exception cref="System.ArgumentException">If cannot find value field by object type.</exception>
/// <returns>Returns object custom attribute if exist.</returns>
private static TAttr GetAttribute<T, TAttr>(this T val)
where TAttr : Attribute
{
if (val == null)
throw new ArgumentNullException(nameof(val));
Type type = val.GetType().GetTypeInfo();
FieldInfo field = type.GetField(val.ToString());
if (field == null)
throw new ArgumentException($"Cannot find field {val.ToString()} by object type {type.Name}");
return field.GetCustomAttribute<TAttr>();
}
/// <summary>
/// Get value by <see cref="DisplayAttribute"/> field from Enum object.
/// </summary>
/// <typeparam name="TType">Return type of result</typeparam>
/// <typeparam name="TEnum">Type of enum struct</typeparam>
/// <param name="value">Enum value.</param>
/// <param name="func">Func for select value</param>
/// <exception cref="System.ArgumentNullException"></exception>
/// <exception cref="System.Resources.MissingManifestResourceException"></exception>
/// <returns>Result of current type object.</returns>
private static TType GetDisplayAttributeValue<TType, TEnum>(this TEnum value, Func<DisplayAttribute,TType> func)
where TEnum : struct
{
DisplayAttribute attr = value.GetAttribute<TEnum,DisplayAttribute>();
if (attr == null)
return default(TType);
if (attr.ResourceType != null)
{
// create new resource manager
ResourceManager manager = new ResourceManager(attr.ResourceType);
// get entry by manager from currect culture locale
DictionaryEntry entry = manager.GetResourceSet(Thread.CurrentThread.CurrentUICulture, true, true).OfType<DictionaryEntry>().SingleOrDefault(x => x.Key.ToString() == func(attr)?.ToString());
// main exceptions
// 1. if locale not found - exception
// 2. if cannot cast to DistionaryEntry type
// 3. if don't single at collection
// 4. if "func" function is not correct
if(entry.Value != null)
return (TType)entry.Value;
}
// run func when resource don't use or found
return func(attr);
}
/// <summary>
/// Get from enum value type name by <see cref="DisplayAttribute"/>.
/// </summary>
/// <typeparam name="TEnum">Enum type.</typeparam>
/// <param name="val">Value of object.</param>
/// <returns> Returns name by enum object at <see cref="DisplayAttribute"/> field <see cref="DisplayAttribute.Name"/>.</returns>
public static string GetName<TEnum>(this TEnum val)
where TEnum : struct
{
return val.GetDisplayAttributeValue(x => x.GetName());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment