1. 程式人生 > 其它 >C# 列舉值轉換為特定字串並支援國際化的方案

C# 列舉值轉換為特定字串並支援國際化的方案

總是有將列舉值輸出成特定字串的需求。假設物體的位置用一個列舉類表示:

public enum ObjectLocationEnum
    {
        Top,
        Bottom,
        Left,
        Right,
    }

UI或者其他地方獲取到該列舉的一個值ObjectLocationEnum.Top ,卻期望在當前程式語言為中文時顯示“上方”、為英文時顯示"upper",甚至在以後的某一天又希望當前程式語言為中文時顯示”上面“而不是以前的“上方”。

很顯然,上述程式碼做不到。在設計列舉型別時將Top硬編碼成其它字元比如”上方“、”上面“然後直接instance.ToString()

同樣是不滿足需求的。

另建一個Dictionary<ObjectLocationEnum, string> ,通過key找到對應的字串(或者找到字串關鍵字,再根據當前語言找到對應字串)雖然可以滿足需求,但其不僅不優雅,而且以後增加列舉項時要維護多處。

可以通過自定義特性(Attribute)優雅的達到這個目的。

定義EnumResStrAttribute 類:

[AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
    public sealed class EnumResStrAttribute : Attribute
    {
        
public string Key { get; } //關鍵字 public string DefaultStr { get; } //預設字串 public EnumResStrAttribute(string key, string defaultStr = null) : base() { Key = key; DefaultStr = defaultStr ?? key; } }

然後在列舉類中應用該特性:

public enum ObjectLocationEnum
    {
        [EnumResStr(key: 
"top", defaultStr: "頂部")] Top, [EnumResStr("bottom", "底部")] Bottom, [EnumResStr("left", "左方")] Left, [EnumResStr("right", "右方")] Right, }

定義一個幫助類:

public static class EnumResStrHelper
    {
        public static string GetResStr(Enum value)
        {
            System.Diagnostics.Debug.Assert(value != null); //測試用,斷言value不為空
            if (value == null) throw new ArgumentNullException("value");
            var fieldInfo = value.GetType().GetField(value.ToString());
            EnumResStrAttribute resStr = (EnumResStrAttribute)Attribute.GetCustomAttribute(fieldInfo, typeof(EnumResStrAttribute));
            return string.IsNullOrEmpty(resStr.Key) ? resStr.DefaultStr : GetLanguageStr(resStr.Key, resStr.DefaultStr);
        }
        //模擬國際化
        private static string GetLanguageStr(string key, string defaultStr)
        {
            string localStr;
            //如果是英文,返回英文
            if (System.Threading.Thread.CurrentThread.CurrentUICulture.Name == "en")
            {
                switch (key)
                {
                    case "top": localStr = "ding"; break;
                    case "bottom": localStr = "di"; break;
                    case "left": localStr = "zuo"; break;
                    case "right": localStr = "you"; break;
                    default: localStr = defaultStr; break;
                }
            }
            else
            {
                switch (key)
                {
                    case "top": localStr = "頂部"; break;
                    case "bottom": localStr = "底部"; break;
                    case "left": localStr = "左方"; break;
                    case "right": localStr = "右方"; break;
                    default: localStr = defaultStr; break;
                }
            }
            return localStr;
        }
    }

大功告成,現在想要獲得列舉對應的特定字串只需要如此呼叫:EnumResStrHelper.GetResStr(ObjectLocationEnum.Top)

除了自定義特性外,也可瞭解下.net提供的System.ComponentModel.DataAnnotations.DisplayAttribute