zoukankan      html  css  js  c++  java
  • 枚举的多语言显示(2)——使用Attribute

    还是jhh0111昨天关于枚举的双语显示问题的帖子的问题,有不少人跟贴询问使用Attribute的实现,于是刚才乘午间休息实现了一个,这里share一下。
    主要框架还是和枚举的多语言显示里一样,对Enum包装了一个DataSource,唯一不同的是里面的每一个Item的DisplayValue采用从Attribute读出,所以这里就不再贴出EnumDataSource代码了(请参考枚举的多语言显示),这里仅仅列出和上篇不同的地方:
     1public string DisplayValue
     2{
     3    get
     4    {
     5        Dictionary<CultureInfo, EnumItemDescriptionAttribute> disc =
     6            EnumItemDescriptionAttribute.GetDisplayValues(_value, typeof(EnumType));
     7        CultureInfo currentUICulute = Thread.CurrentThread.CurrentUICulture;
     8        if (disc.ContainsKey(currentUICulute))
     9            return disc[currentUICulute].Description;
    10        return _value.ToString();
    11    }

    12}
    这里取值是通过EnumItemDescriptionAttribute上的静态Helper方法提供,如果找到对应Culture的Attribute就应用,否则返回默认值(枚举的ToString)。
    显然这里的静态方法是很重要的,通过它就可以访问枚举的额外信息了:
      1/// <summary>
      2///   Define the item of special enum used attribute, you can use it mulitple for multi-descript one enum item.
      3/// </summary>

      4[AttributeUsage(AttributeTargets.Field, AllowMultiple=true)]
      5public class EnumItemDescriptionAttribute : Attribute
      6{
      7    /// <summary>
      8    ///   A cache store, because accessing Attribute is according to reflection, it cost too much
      9    ///   So I add a cache, which based on special enum Type.
     10    /// </summary>

     11    private static readonly Dictionary<Type, Dictionary<object, Dictionary<CultureInfo, EnumItemDescriptionAttribute>>> _cache = 
     12        new Dictionary<Type,Dictionary<object, Dictionary<CultureInfo, EnumItemDescriptionAttribute>>>();
     13    /// <summary>
     14    ///   the culture of Description
     15    /// </summary>

     16    private CultureInfo _culture;
     17    /// <summary>
     18    ///   the description content.
     19    /// </summary>

     20    private string _description;
     21
     22    /// <summary>
     23    ///   Constructor a new <see cref="EnumItemDescriptionAttribute"/> with special culture name and description.
     24    /// </summary>
     25    /// <param name="cultureName">the name of special culture, like en-US, zh-CN etc.</param>
     26    /// <param name="description">the content of Descroption</param>

     27    public EnumItemDescriptionAttribute(string cultureName, string description)
     28        : this(CultureInfo.GetCultureInfo(cultureName), description)
     29    {
     30    }

     31
     32    /// <summary>
     33    ///   Constructor a new <see cref="EnumItemDescriptionAttribute"/> with special culture id and description.
     34    /// </summary>
     35    /// <param name="cultureId">the ID of special culture, like 1033 etc.</param>
     36    /// <param name="description">the content of Descroption</param>

     37    public EnumItemDescriptionAttribute(int cultureId, string description)
     38        : this(CultureInfo.GetCultureInfo(cultureId), description)
     39    {
     40    }

     41
     42    /// <summary>
     43    ///   Internal constructor.
     44    /// </summary>
     45    /// <param name="culture">special <see cref="CultureInfo"/></param>
     46    /// <param name="description">the content of Descroption</param>

     47    private EnumItemDescriptionAttribute(CultureInfo culture, string description)
     48    {
     49        _culture = culture;
     50        _description = description;
     51    }

     52
     53    /// <summary>
     54    ///   Gets the <see cref="CultureInfo"/> for current decription.
     55    /// </summary>

     56    public CultureInfo Culture
     57    {
     58        get return _culture; }
     59    }

     60
     61    /// <summary>
     62    ///   Gets the description content.
     63    /// </summary>

     64    public string Description
     65    {
     66        get return _description; }
     67    }

     68
     69    /// <summary>
     70    ///   Gets all <see cref="EnumItemDescriptionAttribute"/>
     71    ///   for special enum value: <paramref name="value"/> and special enum type: <paramref name="enumType"/>.
     72    /// </summary>
     73    /// <param name="value">the value of special enum</param>
     74    /// <param name="enumType">the enum type of special enum</param>
     75    /// <returns>All attributes attatched on special enum value.</returns>

     76    public static Dictionary<CultureInfo, EnumItemDescriptionAttribute> GetDisplayValues(object value, Type enumType)
     77    {
     78        if (enumType == null || !enumType.IsEnum)
     79        {
     80            throw new NotSupportedException("enumType is not a Enum");
     81        }

     82        if (value == null || !Enum.IsDefined(enumType, value))
     83        {
     84            throw new ArgumentException("value is not defined in " + enumType.FullName);
     85        }

     86
     87        return GetDisplayValuesImp(value, enumType);
     88    }

     89
     90    /// <summary>
     91    ///   Gets the <see cref="EnumItemDescriptionAttribute"/> for special enum value: <paramref name="value"/>,
     92    ///   special enum type: <paramref name="enumType"/> and special culture.
     93    /// </summary>
     94    /// <param name="value">the value of special enum</param>
     95    /// <param name="enumType">the enum type of special enum</param>
     96    /// <param name="culture">special culture for item description.</param>
     97    /// <returns>The attributes attatched on special enum value.</returns>

     98    public static string GetDisplayValue(object value, Type enumType, CultureInfo culture)
     99    {
    100        if (enumType == null || !enumType.IsEnum)
    101        {
    102            throw new NotSupportedException("enumType is not a Enum");
    103        }

    104        if (value == null || !Enum.IsDefined(enumType, value))
    105        {
    106            throw new ArgumentException("value is not defined in " + enumType.FullName);
    107        }

    108
    109        if (culture == null)
    110            return value.ToString();
    111
    112        Dictionary<CultureInfo, EnumItemDescriptionAttribute> disc = GetDisplayValuesImp(value, enumType);
    113        if (disc.ContainsKey(culture))
    114            return disc[culture].Description;
    115        return value.ToString();
    116    }

    117
    118    /// <summary>
    119    ///   Gets all <see cref="EnumItemDescriptionAttribute"/>
    120    ///   for special enum value: <paramref name="value"/> and special enum type: <paramref name="enumType"/>.
    121    /// </summary>
    122    /// <param name="value">the value of special enum</param>
    123    /// <param name="enumType">the enum type of special enum</param>
    124    /// <returns>All attributes attatched on special enum value.</returns>

    125    private static Dictionary<CultureInfo, EnumItemDescriptionAttribute> GetDisplayValuesImp(object value, Type enumType)
    126    {
    127        if (!_cache.ContainsKey(enumType))
    128        {
    129            Dictionary<object, Dictionary<CultureInfo, EnumItemDescriptionAttribute>> displayValues =
    130                new Dictionary<object, Dictionary<CultureInfo, EnumItemDescriptionAttribute>>();
    131            foreach (Enum item in Enum.GetValues(enumType))
    132            {
    133                Dictionary<CultureInfo, EnumItemDescriptionAttribute> descriptions =
    134                    new Dictionary<CultureInfo, EnumItemDescriptionAttribute>();
    135                FieldInfo enumField = enumType.GetField(item.ToString());
    136                if (enumField != null)
    137                {
    138                    foreach (EnumItemDescriptionAttribute desc
    139                        in enumField.GetCustomAttributes(typeof(EnumItemDescriptionAttribute), true))
    140                    {
    141                        descriptions.Add(desc.Culture, desc);
    142                    }

    143                }

    144                displayValues.Add(item, descriptions);
    145            }

    146            _cache.Add(enumType, displayValues);
    147        }

    148
    149        return _cache[enumType][value];
    150    }

    151}
    使用示例如下:
     1private void Form1_Load(object sender, EventArgs e)
     2{
     3    this.comboBox1.DataSource = new EnumDataSource2<Sex>();
     4    this.comboBox1.DisplayMember = "DisplayValue";
     5    this.comboBox1.ValueMember = "Value";
     6}

     7
     8public enum Sex
     9{
    10    [EnumItemDescription("zh-CN""")]
    11    [EnumItemDescription("ja""男性")]
    12    [EnumItemDescription("de""Männliche")]
    13    Male,
    14    [EnumItemDescription("zh-CN""")]
    15    [EnumItemDescription("ja""女性")]
    16    [EnumItemDescription("de""Weibliche")]
    17    Female
    18}
    你可以从这里下载本篇中的相关示例代码:
    https://files.cnblogs.com/winkingzhang/Demo_2008_03_26.rar
  • 相关阅读:
    numpy-tutorial
    Pandas 数据分析资料
    python3 创建虚拟环境
    机器学习中的评价指标--02
    机器学习中的评价指标--01
    pytest 测试框架
    Ubuntu 添加删除用户
    VSCODE 设置护眼颜色
    信息熵、交叉熵、KL散度等等
    深度学习优化方法演变和公式理解
  • 原文地址:https://www.cnblogs.com/winkingzhang/p/1123075.html
Copyright © 2011-2022 走看看