在項目開發中我們經常會用枚舉,一般情況下我們為枚舉定義了一些類型在使用的時候都要根據枚舉的值來判斷,我們可以利用 Attribute 來實現。
在定義枚舉的時候增加描述屬性:
/// <summary>
/// 定義接口請求狀態枚舉。
/// </summary>
public enum StatusCode
{
/// <summary>
/// 操作成功。
/// </summary>
[EnumDescription("操作成功")]
Success = 1,
/// <summary>
/// 操作失敗。
/// </summary>
[EnumDescription("操作失敗")]
Error = 0
}
EnumDescriptionAttribute 定義如下:
/// <summary>
/// 枚舉描述屬性,使用 EnumDescriptionAttribute 以透明獲取的枚舉值描述信息。
/// </summary>
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public class EnumDescriptionAttribute : Attribute
{
#region Fields...
/// <summary>
/// 初始化枚舉值描述文本緩存。
/// </summary>
private static Dictionary<string, string> dic = new Dictionary<string, string>();
#endregion
#region Properties...
/// <summary>
/// 獲取或設置枚舉值描述文本。
/// </summary>
public string Description{ get; set; }
#endregion
#region Methods...
/// <summary>
/// 獲取指定枚舉值的描述文本。
/// </summary>
/// <param name="enumValue">指定枚舉值。</param>
/// <returns>指定枚舉值的描述文本。</returns>
public virtual string GetDescription(object enumValue)
{
if (enumValue != null)
{
return Description ?? enumValue.ToString();
}
else
{
return String.Empty;
}
}
/// <summary>
/// 獲取指定枚舉值的描述文本。
/// </summary>
/// <param name="enumValue">指定枚舉值。</param>
/// <returns>指定枚舉值的描述文本。</returns>
public static string GetDescription(Enum enumValue)
{
//獲取指定枚舉值的枚舉類型。
Type type = enumValue.GetType();
string key = GetCacheKey(type, enumValue.ToString());
//如果緩存存在,直接返回緩存的枚舉值描述文本。
if (dic.ContainsKey(key))
{
return dic[key];
}
FieldInfo fieldInfo = type.GetField(enumValue.ToString());
if (fieldInfo != null)
{
//獲得枚舉中各個字段的定義數組
var atts = (EnumDescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(EnumDescriptionAttribute), false);
if (atts.Length > 0)
{
dic[key] = atts[0].Description;
return atts[0].Description;
}
}
return enumValue.ToString();
}
/// <summary>
/// 以得到指定枚舉類型的所有枚舉值的由 EnumDescriptionAttribute 或其繼承類標注的描述信息
/// </summary>
/// <param name="enumType"></param>
/// <param name="enumIntValue"></param>
/// <returns></returns>
public static string GetDescription(Type enumType, int enumIntValue)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
Dictionary<int, string> descs = EnumDescriptionAttribute.GetDescriptions(enumType);
Dictionary<int, string>.Enumerator en = descs.GetEnumerator();
while (en.MoveNext())
{
if ((enumIntValue & en.Current.Key) == en.Current.Key)
{
if (sb.Length == 0)
{
sb.Append(en.Current.Value);
}
else
{
sb.Append(',');
sb.Append(en.Current.Value);
}
}
}
return sb.ToString();
}
public static Dictionary<int, string> GetDescriptions(Type enumType)
{
Dictionary<int, string> descs = new Dictionary<int, string>();
if (enumType != null && enumType.IsEnum)
{
FieldInfo[] fields = enumType.GetFields();
for (int i = 1; i < fields.Length; ++i)
{
object fieldValue = Enum.Parse(enumType, fields[i].Name);
object[] attrs = fields[i].GetCustomAttributes(true);
bool findAttr = false;
foreach (object attr in attrs)
{
if (typeof(EnumDescriptionAttribute).IsAssignableFrom(attr.GetType()))
{
descs.Add((int)fieldValue, ((EnumDescriptionAttribute)attr).GetDescription(fieldValue));
findAttr = true;
break;
}
}
if (!findAttr)
{
descs.Add((int)fieldValue, fieldValue.ToString());
}
}
}
return descs;
}
#region Private Methods...
/// <summary>
/// 獲取指定枚舉值描述文本緩存鍵。
/// </summary>
/// <param name="type">指定枚舉類型。</param>
/// <param name="enumStrValue">指定枚舉值字符串。</param>
/// <returns>指定枚舉值描述文本緩存鍵。</returns>
private static string GetCacheKey(Type type, string enumStrValue)
{
return type.ToString() + "_" + enumStrValue;
}
#endregion
#endregion
}
在使用的時候只需要調用 GetDescription 方法即可。
EnumDescriptionAttribute.GetDescription(StatusCode.Success)
