1. 程式人生 > >.Net下列舉的巧用

.Net下列舉的巧用

使用者故事:

  下圖是系統中一組基於位運算的類別,其值分別為1,2,4,8,16。由於可以進行隨意組合,所以落庫值為[1,31]區間的任意值。

  

  我們需要在頁面上展示所有的組合,如下圖:

  

 

  如果使用if或者switch語句根據組合來輸出組合對應的文字,那麼就要寫從[1,31]區間31種條件表示式,程式碼充斥著腐朽的味道。如果需求變動,再加幾個類別的話。。。不好,是心肌梗塞的感覺:

 switch (rcType)
            {
                case 1:
                    rcTypeDes 
= "低價RC"; break; case 2: rcTypeDes = "提前天數RC"; break; case 3: rcTypeDes = "低價RC,提前天數RC"; break; case 4: rcTypeDes = "艙等RC";
break; case 5: rcTypeDes = "低價RC,艙等RC"; break; case 6: rcTypeDes = "提前天數RC,艙等RC"; break; case 7: rcTypeDes = "低價RC,提前天數RC,艙等RC"; break
; case 8: rcTypeDes = "協議RC"; break; case 9: rcTypeDes = "低價RC,協議RC"; break; case 10: rcTypeDes = "提前天數RC,協議RC"; break; case 11: rcTypeDes = "低價RC,提前天數RC,協議RC"; break; case 12: rcTypeDes = "艙等RC,協議RC"; break; case 13: rcTypeDes = "低價RC,艙等RC,協議RC"; break; case 14: rcTypeDes = "提前天數RC,艙等RC,協議RC"; break; case 15: rcTypeDes = "低價RC,提前天數RC,艙等RC,協議RC"; break; case 16: rcTypeDes = "公里數RC"; break; case 17: rcTypeDes = "低價RC,公里數RC"; break; case 18: rcTypeDes = "提前天數RC,公里數RC"; break; case 19: rcTypeDes = "低價RC,提前天數RC,公里數RC"; break; case 20: rcTypeDes = "艙等RC,公里數RC"; break; case 21: rcTypeDes = "低價RC,艙等RC,公里數RC"; break; case 22: rcTypeDes = "提前天數RC,艙等RC,公里數RC"; break; case 23: rcTypeDes = "低價RC,提前天數RC,艙等RC,公里數RC"; break; case 24: rcTypeDes = "協議RC,公里數RC"; break; case 25: rcTypeDes = "低價RC,協議RC,公里數RC"; break; case 26: rcTypeDes = "提前天數RC,協議RC,公里數RC"; break; case 27: rcTypeDes = "低價RC,提前天數RC,協議RC,公里數RC"; break; case 28: rcTypeDes = "艙等RC,協議RC,公里數RC"; break; case 29: rcTypeDes = "低價RC,艙等RC,協議RC,公里數RC"; break; case 30: rcTypeDes = "提前天數RC,艙等RC,協議RC,公里數RC"; break; case 31: rcTypeDes = "低價RC,艙等RC,協議RC,公里數RC,公里數RC"; break; }

 

解決方案:

  在C#中,Enum物件提供了GetValues(Enum)方法,遍歷指定的列舉物件獲得一個Array物件,我們可以通過傳入的組合(比如3)來和Array中的元素進行對比,利用Enum.HasFlag可以判斷是否滿足位運算的結果,比如組合為3,當前遍歷到的類別元素為1,那麼HasFlag為真:

  

 public static class EnumDescriptionHelp
    {

        /// <summary>
        /// 列舉值獲取Description資訊/// </summary>
        /// <param name="EnumValue"></param>
        /// <param name="enumType"></param>
        /// <returns></returns>
        public static List<String> GetEnumValueDescriptions(int EnumValue, Type enumType)
        {
            List<string> strs = new List<string>();

            var enumvalues = Enum.GetValues(enumType);

            Enum temp = (Enum)Enum.ToObject(enumType, EnumValue);

            foreach (var temp2 in enumvalues)
            {
                if (temp.HasFlag((Enum)temp2))
                {
                    strs.Add((temp2 as Enum).GetDescription());
                }
            }

            return strs;
        }
}

  public enum FlightRCTypeEnum : int
        {
            /// <summary>
            /// 低價RC
            /// </summary>
            [Description("低價RC")]
            LowRC = 1,

            /// <summary>
            /// 提前RC
            /// </summary>
            [Description("提前RC")]
            AdvRC = 2,

            /// <summary>
            /// 艙等RC
            /// </summary>
            [Description("艙等RC")]
            ClassRC = 4,

            [Description("協議RC")]
            ProtocolRc = 8,

            [Description("公里數RC")]
            DistanceRC = 16
        }

 

呼叫程式碼:  

 List<string> enumList = EnumDescriptionHelp.GetEnumValueDescriptions(rcType, typeof(FlightRCTypeEnum));
 return enumList.Any() ? string.Join(",", enumList) : "";

 

 總結:

  在程式中巧用位運算,很多時候可以達到事半功倍的效果,特別是對於那些需要列舉的屬性值來講。但是技巧只是第一步,如何在程式碼層面使用好這個技巧,需要我們在編碼的時候多想一步,為系統,為自己也為後來者提供一個易讀,易維護的程式碼環境。