C# 列舉值轉換為特定字串並支援國際化的方案
阿新 • • 發佈:2021-10-15
總是有將列舉值輸出成特定字串的需求。假設物體的位置用一個列舉類表示:
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 。