日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

常用扩展之枚举扩展

發(fā)布時(shí)間:2025/7/25 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 常用扩展之枚举扩展 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

項(xiàng)目在開發(fā)的過程中,經(jīng)常會(huì)遇到一些前臺(tái)顯示和后臺(tái)代碼不相同的屬性,比如布爾類型和枚舉類型的屬性要轉(zhuǎn)換為相應(yīng)的中文說明。而且,轉(zhuǎn)換也會(huì)有千變?nèi)f化的可能,轉(zhuǎn)換為一個(gè)下拉列表框和網(wǎng)格中的一個(gè)列就不一樣。

這個(gè)時(shí)候,可能會(huì)有幾種解決方案:最簡(jiǎn)單的就是使用switch語句,寫成一個(gè)擴(kuò)展方法,然后在前臺(tái)綁定的時(shí)候使用擴(kuò)展方法解決。這種方法簡(jiǎn)單,但是沒遇到一種就得寫一個(gè)擴(kuò)展方法,不具有通用性。

我這里要說的是基于Attribute的一種比較通用的方案。我們都知道,.Net能夠在類的成員上添加特性(Attribute),增加一些我們自己定制的東西。所以,我就在枚舉的這些成員上加上了一個(gè)自定義的特性,保存我要轉(zhuǎn)換的中文注釋。我自定義的特性代碼如下:

/// <summary> /// 字段或?qū)傩缘闹形慕忉寣傩?/span> /// </summary> [Serializable] [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)] public class Desc : Attribute { /// <summary> /// 獲得字段或?qū)傩缘闹形慕忉? /// </summary> /// <value>字段或?qū)傩缘闹形慕忉?</value> public string Value { get; private set; } /// <summary> /// 初始化創(chuàng)建一個(gè) <see cref="Desc"/> 類的實(shí)例, 用于指示字段或?qū)傩缘慕忉屨f明. /// </summary> /// <param name="value">字段或?qū)傩缘慕忉屨f明.</param> public Desc(string value) { Value = value; } }

之后,通過反射獲取這個(gè)屬性,進(jìn)而獲取我編程的時(shí)候?yàn)槠涮砑拥闹形淖⑨?。做成擴(kuò)展方法之后,就可以對(duì)所有的枚舉使用了。不過因?yàn)槭褂昧朔瓷?#xff0c;在密集調(diào)用的時(shí)候效率上會(huì)損失一點(diǎn),不知道各位有沒有更好的解決方案。

/// <summary> /// 獲得枚舉字段的特性(Attribute),該屬性不允許多次定義。 /// </summary> /// <typeparam name="T">特性類型。</typeparam> /// <param name="value">一個(gè)枚舉的實(shí)例對(duì)象。</param> /// <returns>枚舉字段的擴(kuò)展屬性。如果不存在則返回 <c>null</c> 。</returns> public static T GetAttribute<T>(this Enum value) where T : Attribute { FieldInfo field = value.GetType().GetField(value.ToString()); return Attribute.GetCustomAttribute(field, typeof(T)) as T; }

我先說明一下,C#里面所有的枚舉(enum)都是從Enum這個(gè)類繼承的。所以將Enum填在這里,就能在所有的枚舉實(shí)例上使用這個(gè)擴(kuò)展方法。

約束T類型必須從Attribute這個(gè)類繼承,是因?yàn)镃#中規(guī)定能夠追加在字段上的特性必須從Attribute類繼承。對(duì)于這一點(diǎn)不理解的話,通過Google搜索一下,應(yīng)該很快就可以得到答案。

經(jīng)過了這兩個(gè)準(zhǔn)備之后,只要我們?cè)诿杜e的成員上加上了特性,就能夠通過這個(gè)擴(kuò)展方法訪問了,而且不局限于我提供的這個(gè)屬性。我這里舉個(gè)例子簡(jiǎn)單說明一下:

/// <summary> /// 客戶狀態(tài) /// </summary> [Serializable] public enum CustomerStateType { /// <summary> /// [默認(rèn)值] 活動(dòng)狀態(tài)。 /// </summary> [Desc("活動(dòng)")] Active = 0, ? /// <summary> /// 終止?fàn)顟B(tài)。 /// </summary> [Desc("終止")] End = 1, }

定義完了之后,我們就可以通過擴(kuò)展方法獲得這個(gè)所謂的“活動(dòng)”和“終止”了。代碼如下:

// 假設(shè)這里是經(jīng)過了一系列計(jì)算得到的結(jié)果。 CustomerStateType state = CustomerStateType.Active; ? // 這里是想要獲得的結(jié)果。 string result = string.Empty; ? // 這就是我向你們展示的部分。 Desc description = state.GetAttribute<Desc>(); if (description != null) result = description.Value;

我這里對(duì)于密集調(diào)用還有一個(gè)解決方案,正是針對(duì)于文章開始所說的列表中的枚舉轉(zhuǎn)換。上述擴(kuò)展方法的調(diào)用雖然會(huì)損失一些效率,但是可以通過緩存來解決這個(gè)問題。先給大家看最終的效果:

private static Dictionary<CustomerStateType, string> _customerState = null; /// <summary> /// 獲得客戶狀態(tài)字典 /// </summary> public static Dictionary<CustomerStateType, string> CustomerStates { get { if (_customerState == null) _customerState = Enum<CustomerStateType>.AsEnumerable() .ToDictionary(p => p, p => p.GetAttribute<Desc>().Value); ? return _customerState; } }

可以看到這是一個(gè)靜態(tài)屬性,放在字典中。想要獲取的時(shí)候可以通過鍵獲得相應(yīng)的中文解釋。代碼中的Enum<>類是我從CoolCode那竊取了一點(diǎn)想法,用于將一個(gè)枚舉類型轉(zhuǎn)換為IEnumable<>的可迭代序列。其代碼如下:

/// <summary> /// T 類型枚舉列表 /// </summary> /// <typeparam name="T">枚舉類型</typeparam> public class Enum<T> : IEnumerable<T> { #region Business Methods /// <summary> /// 返回類型為 IEnumerable&lt;T&gt; 的輸入。 /// </summary> /// <returns>類型為 IEnumerable&lt;T&gt; 的序列。</returns> public static IEnumerable<T> AsEnumerable() { return new Enum<T>(); } #endregion ? #region IEnumerable<T> 成員 ? /// <summary> /// 返回一個(gè)循環(huán)訪問集合的枚舉數(shù)。 /// </summary> /// <returns>可用于循環(huán)訪問集合的 IEnumerator&lt;T&gt; 。</returns> public IEnumerator<T> GetEnumerator() { return Enum.GetValues(typeof(T)) .OfType<T>() .AsEnumerable() .GetEnumerator(); } ? #endregion ? #region IEnumerable 成員 ? /// <summary> /// 返回一個(gè)循環(huán)訪問集合的枚舉數(shù)。 /// </summary> /// <returns>可用于循環(huán)訪問集合的 IEnumerator 。</returns> IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } ? #endregion ? #region IEnumerable<T> 成員 ? /// <summary> /// 返回一個(gè)循環(huán)訪問集合的枚舉數(shù)。 /// </summary> /// <returns> /// <returns>可用于循環(huán)訪問集合的 IEnumerator&lt;T&gt; 。</returns> IEnumerator<T> IEnumerable<T>.GetEnumerator() { return GetEnumerator(); } ? #endregion }

這個(gè)類很簡(jiǎn)單,就是將枚舉類型的所有成員以一個(gè)IEnumable的形式展示,但是并沒有做額外的工作。但就是這樣,使得我們有了強(qiáng)大的擴(kuò)展功能,比如上面我所做的那個(gè)緩存字典。

我還有點(diǎn)不放心的是,文中用到了很多微軟提供給我們的Linq擴(kuò)展方法,不知道大家能明白多少。不過沒關(guān)系,園子里的LINQ專題可以提供參考。相信這不是什么問題!關(guān)于LINQ的東西,我不想過多的發(fā)表觀點(diǎn),這里用一句話表明吧:很強(qiáng)大,能讓你在.Net平臺(tái)上走得更遠(yuǎn)!

當(dāng)然,這個(gè)問題的解決方案肯定不止上面我提到的這兩種,聰明的你肯定還有其它的更好的方法,不妨寫出來,讓大家分享一下。

轉(zhuǎn)載于:https://www.cnblogs.com/lenic/archive/2011/01/13/1934209.html

總結(jié)

以上是生活随笔為你收集整理的常用扩展之枚举扩展的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。