c#擴充方法奇思妙用基礎篇五:Dictionary 擴充

來源:互聯網
上載者:User

 

 

Dictionary<TKey, TValue> 類是常用的一個基礎類,但用起來有時確不是很方便。本文逐一討論,並使用擴充方法解決。

向字典中添加鍵和值

添加鍵和值使用 Add 方法,但很多時候,我們是不敢輕易添加的,因為 Dictionary<TKey, TValue> 不允許重複,嘗試添加重複的鍵時 Add 方法引發 ArgumentException。

大多時候,我們都會寫成以下的樣子:

var dict = new Dictionary<int, string>();// ...// 情形一:不存在才添加if (dict.ContainsKey(2) == false) dict.Add(2, "Banana");// 情形二:不存在添加,存在則替換if (dict.ContainsKey(3) == false) dict.Add(3, "Orange");else dict[3] = "Orange";

其實,第二種情形可以寫如下書寫(請參見 http://msdn.microsoft.com/zh-cn/library/9tee9ht2.aspx):

dict[3] = "Orange";

不過好多朋友都會對這種方式表示疑慮,不太確定這樣會不會出問題。

 

不管是上面的哪種寫法,用字典時最大的感覺就是擔心,怕出異常,因此代碼會寫的很羅嗦。

我每次用字典時都這樣,時間長了,實在是厭煩了,索性擴充一下,用以下兩個方法來應對上面兩種情形:

/// <summary>/// 嘗試將鍵和值添加到字典中:如果不存在,才添加;存在,不添加也不拋導常/// </summary>public static Dictionary<TKey, TValue> TryAdd<TKey, TValue>(this Dictionary<TKey, TValue> dict, TKey key, TValue value){    if (dict.ContainsKey(key) == false) dict.Add(key, value);    return dict;}/// <summary>/// 將鍵和值添加或替換到字典中:如果不存在,則添加;存在,則替換/// </summary>public static Dictionary<TKey, TValue> AddOrReplace<TKey, TValue>(this Dictionary<TKey, TValue> dict, TKey key, TValue value){    dict[key] = value;    return dict;}

TryAdd 和 AddOrReplace 這兩個方法具有較強自我描述能力,用起來很省心,而且也簡單:

dict.TryAdd(2, "Banana");dict.AddOrReplace(3, "Orange");

或者像 Linq 或 jQuery 一樣連起來寫:

dict.TryAdd(1, "A")    .TryAdd(2, "B")    .AddOrReplace(3, "C")    .AddOrReplace(4, "D")    .TryAdd(5, "E");

再來看另外一個問題:

擷取值

從字典中擷取值通常使用如下方式:

string v = "defaultValue";// 方式一if (dict.ContainsKey(3)) v = dict[3];// 方式二bool isSuccess = dict.TryGetValue(3, out v);

使用索引的方式擷取前一定先判斷,否則不存在時會引發 KeyNotFoundException 異常。

我尤其討厭第二種方式,因為採用 out 要提前聲明一個變數,代碼至少要兩行,不夠簡潔。

看下 GetValue 擴充:

/// <summary>/// 擷取與指定的鍵相關聯的值,如果沒有則返回輸入的預設值/// </summary>public static TValue GetValue<TKey, TValue>(this Dictionary<TKey, TValue> dict, TKey key, TValue defaultValue = default(TValue)){    return dict.ContainsKey(key) ? dict[key] : defaultValue;}

使用方便:

var v1 = dict.GetValue(2);         //不存在則返回 nullvar v2 = dict.GetValue(2, "abc");  //不存在返回 ”abc“

一行代碼能搞定。

大量新增

List<T> 類有個 AddRange 方法,可以不用 foreach 迴圈直接向當前集合加入另外一個集合:

List<string> roles = new List<string>();roles.AddRange(new[] { "role2", "role2" });roles.AddRange(user.GetRoles());

相當方便,可憐 Dictionary<TKey, TValue> 類沒有,幸好有擴充方法:

/// <summary>/// 向字典中大量新增索引值對/// </summary>/// <param name="replaceExisted">如果已存在,是否替換</param>public static Dictionary<TKey, TValue> AddRange<TKey, TValue>(this Dictionary<TKey, TValue> dict, IEnumerable<KeyValuePair<TKey, TValue>> values, bool replaceExisted){    foreach (var item in values)    {        if (dict.ContainsKey(item.Key) == false || replaceExisted)            dict[item.Key] = item.Value;    }    return dict;}

使用樣本:

var dict1 = new Dictionary<int, int>()    .AddOrReplace(2, 2)    .AddOrReplace(3, 3);var dict2 = new Dictionary<int, int>()    .AddOrReplace(1, 1)    .AddOrReplace(2, 1)    .AddRange(dict1, false);

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.